def each_glyph_to_aiff(): # chords f = CurrentFont() #m = 0 for n in f.selection: a = aifc.open("aiff_out/%s_%s.aiff" % (str(f.info.familyName), n), "wb") a.setnchannels(1) a.setsampwidth(2) a.setframerate(44100) g = f[n] flattenGlyph(g, 4) print "Glyph:", g.name #m += 1 #a.setmark(m, a.tell(), g.name) cDists = {} for i in range(len(g)): cList = [] c = g[i] b = c.box if b is None: # ignore anchors, they have no bounding box break pCenter = ((b[0] + b[2]) / 2, (b[1] + b[3]) / 2) for p in c.points: cList.append(distance(pCenter, (p.x, p.y), doRound=True)) cDists[i] = cList amps = {} listLengths = [] for k, myList in cDists.iteritems(): listLengths.append(len(myList)) amps[k] = scaleList(myList, 255) print " Loop lengths: %s (samples)" % listLengths loopLength = kgv(listLengths) if loopLength < 44100: loopLength *= 44100 / loopLength if loopLength > 441000: loopLength /= loopLength / 44100 print " Chord loop: %i samples" % loopLength for i in range(int(round(loopLength))): myVal = 0 numWaves = len(amps.keys()) for k in amps.iterkeys(): myVal += getModVal(amps[k], i) myVal /= numWaves a.writeframes(pack("<h", myVal)) #myVal = pack("i", 0) #for i in range(10000): # a.writeframes(myVal) a.close() print "Done."
def copyAndFlat(self, glyphName, font, precision): # Opening glyph glyph = font[glyphName] # Calling the layer glyph_flat = glyph.getLayer("flat", clear=False) # Copy and append glyph_matrix = glyph.copy() glyph_flat.appendGlyph(glyph_matrix) # Flattening flattenGlyph(glyph_flat, precision) return glyph_flat
def copyAndFlat(self, glyphName, font, precision): # Opening glyph glyph = font[glyphName] # Calling the layer glyph_flat = glyph.getLayer('flat', clear=False) # Copy and append glyph_matrix = glyph.copy() glyph_flat.appendGlyph(glyph_matrix) # Flattening flattenGlyph(glyph_flat, precision) return glyph_flat
def randomize_glyph(glyph): source = glyph font = glyph._parent # Save the anchors from the original glyph in a list anchors = [a for a in source.anchors] # Remove all anchors from the glyph so they don't interfere with our processing for a in anchors: source.removeAnchor(a) # Convert to small segments source = flattenGlyph(aGlyph=source, threshold=20, segmentLines=True) # Temporary glyph to which the pen is writing target = RGlyph() target_pen = target.getPen() source_pen = MyPen(font, target_pen, 8) source.draw(source_pen) # Clear the original glyph and add the modfied outline source.clear(components=False) source.appendGlyph(target) # Restore the saved anchors for a in anchors: source.appendAnchor(a.name, a.position)
def all_glyphs_in_one_aiff(): # all tones after another f = CurrentFont() a = aifc.open("aiff_out/aiffContours.aiff", "wb") a.setnchannels(1) a.setsampwidth(4) a.setframerate(44100) m = 0 for n in f.selection: g = f[n] flattenGlyph(g, 4) print g.name m += 1 a.setmark(m, a.tell(), g.name) cDists = {} for i in range(len(g)): cList = [] c = g[i] b = c.box if b is None: # ignore anchors, they have no bounding box break pCenter = ((b[0] + b[2]) / 2, (b[1] + b[3]) / 2) for p in c.points: cList.append(distance(pCenter, (p.x, p.y), doRound=True)) cDists[i] = cList amps = {} for k, myList in cDists.iteritems(): amps[k] = scaleList(myList, 255) for k, v in amps.iteritems(): print k #print v for i in range(100): for myVal in v: a.writeframes(pack("i", myVal)) myVal = pack("i", 0) for i in range(10000): a.writeframes(myVal) a.close() print "Done."
def _makeFlat(aGlyph, segmentLength = 10): """Helper function to flatten the glyph with a given approximate segment length.""" return flattenGlyph(aGlyph, segmentLength)
def _makeFlat(aGlyph, segmentLength=10): """Helper function to flatten the glyph with a given approximate segment length.""" return flattenGlyph(aGlyph, segmentLength)
from robofab.world import CurrentGlyph from robofab.pens.filterPen import flattenGlyph d = 10 flattenGlyph(CurrentGlyph(), d)
def exp_R(self, font, xHeight): # Calling the glyph R = font['R'] # Contours separation (internal, external) internal_level, external_level = self.contours_separation(R) # Flattening contours flattenGlyph(internal_level, 10) flattenGlyph(external_level, 10) # Filtering x values left_stem_x_values = self.filter_points(external_level, 'x') right_stem_x_values = self.filter_points(internal_level, 'x') # Left middle points, occurrences collection left_stem_x_values = self.occurDict(left_stem_x_values) right_stem_x_values = self.occurDict(right_stem_x_values) # Left middle points, reordering occurrences left_stem_x_values = sorted(left_stem_x_values.items(), key=itemgetter(1), reverse=True) right_stem_x_values = sorted(right_stem_x_values.items(), key=itemgetter(1), reverse=True) # Left middle point, x value left_middle_point = (left_stem_x_values[0][0] + right_stem_x_values[0][0]) / 2.0 # Right middle point left_bowl_x_values = self.filter_points(internal_level, 'x') right_bowl_x_values = self.filter_points(external_level, 'xy') # Right middle point, extreme internal left_extreme = max(left_bowl_x_values) # extreme superior right_bowl_x_values = sorted(right_bowl_x_values, key=itemgetter(1), reverse=True) extreme_superior = right_bowl_x_values[0][1] # Filtering the upper half of the glyph right_bowl_x_values = [ item for item in right_bowl_x_values if item[1] >= extreme_superior / 2.0 ] # x values reordering right_bowl_x_values = sorted(right_bowl_x_values, key=itemgetter(0), reverse=True) # Bowl right extreme right_extreme = right_bowl_x_values[0][0] # Right middle point right_middle_point = (right_extreme + left_extreme) / 2.0 # 'R' expansion expansion_R = right_middle_point - left_middle_point # Visual check R_stats = R.getLayer('stats', clear=False) # Middle points self.rect(R_stats, left_middle_point, R.box[3] / 1.5, 2, 2) self.rect(R_stats, right_middle_point, R.box[3] / 1.5, 2, 2) # Extremes self.rect(R_stats, left_extreme, R.box[3] / 2.0, 2, 2) self.rect(R_stats, right_extreme, R.box[3] / 2.0, 2, 2) self.rect(R_stats, left_stem_x_values[0][0], R.box[3] / 2.0, 2, 2) self.rect(R_stats, right_stem_x_values[0][0], R.box[3] / 2.0, 2, 2) return round(expansion_R / xHeight, 4)
def contrast(self, font): # Calling the glyph o = font['o'] # Contours separation internal_level, external_level = self.contours_separation(o) # Flatting the level flattenGlyph(internal_level, 10) internal_points_number = len(internal_level[0]) # External contour length external_length = self.contourLength(external_level[0]) # External segment length d = external_length / internal_points_number # checked flattening flattenGlyph(external_level, d) # contour direction correction internal_level.correctDirection() external_level.correctDirection() # Correction starting points internal_level[0].autoStartSegment() external_level[0].autoStartSegment() # Contour condition if internal_level[0].clockwise == external_level[0].clockwise: pass else: print "There's an error!" # Checking the contour with less points if len(internal_level[0]) <= len(external_level[0]): len_min = len(internal_level[0]) elif len(internal_level[0]) > len(external_level[0]): len_min = len(external_level[0]) # Iteration over the number of contour points distances = [] for i in range(len_min - 1): # Points selection x1 = internal_level[0].points[i].x y1 = internal_level[0].points[i].y distances_detail = [] for l in range(-3, 4): # Estrarre solo quello più corto # Indice di controllo index = i + l if index >= len_min: index = index - len_min x2 = external_level[0].points[index].x y2 = external_level[0].points[index].y # distance between points (Pitagora) distanza = hypot((x1 - x2), (y1 - y2)) # Detail check distances_detail.append((((x1, y1), (x2, y2)), distanza)) # Reordering details list distances_detail = sorted(distances_detail, key=itemgetter(1)) # Collection of the shortest measure distances.append(distances_detail[0]) # Reordering values list distances = sorted(distances, key=itemgetter(1)) # Calling the shortest and the longest thickness shorter_thickness = distances[0][1] greater_thickness = distances[-1][1] # Contrast calculation contrast = shorter_thickness / greater_thickness # Slope shorter thickness calculation angle_min_thick = self.angle_segment(distances[0][0][0], distances[0][0][1]) # Visual check o_stats = o.getLayer('stats', clear=False) self.rect(o_stats, distances[0][0][0][0], distances[0][0][0][1], 2, 2) # shortest self.rect(o_stats, distances[0][0][1][0], distances[0][0][1][1], 2, 2) # shortest self.rect(o_stats, distances[-1][0][0][0], distances[-1][0][0][1], 2, 2) # longest self.rect(o_stats, distances[-1][0][1][0], distances[-1][0][1][1], 2, 2) # longest return round(contrast, 2), int(round(angle_min_thick, 0))
def draw(self, glyph_names=[]): if glyph_names == []: self.font.glyphOrder if self.font is not None: for n in glyph_names: newDrawing() size(self.size[0], self.size[1]) fontSize(24) fill(0.3) glyph = self.font[n] audio_glyph = glyph.copy() flattenGlyph(audio_glyph, 4) x_offset = int(round((self.size[0] - glyph.width * self.scale) / 2)) scale(self.scale) num_steps = max([len(contour) for contour in audio_glyph]) num_frames = 50 # cache wave forms for drawing: make empty dict with # an entry for each contour wave_forms = {} for wave_index in range(len(audio_glyph)): wave_forms[wave_index] = [] for i in range(num_frames): # set up drawing translate(x_offset, self.y_offset) save() fill(0.3) drawGlyph(glyph) for contour_index in range(len(audio_glyph)): contour = audio_glyph[contour_index] if len(contour) > 1: # calculate bounding box and draw a line from center to point bbox = contour.box pCenter = ((bbox[0] + bbox[2])/2, (bbox[1] + bbox[3])/2) segment_index = i * int(round(len(contour) / num_frames)) % len(contour) p = contour[segment_index].points[-1] save() stroke(0) line((pCenter[0] - 5, pCenter[1] - 5), (pCenter[0] + 5, pCenter[1] + 5)) line((pCenter[0] - 5, pCenter[1] + 5), (pCenter[0] + 5, pCenter[1] - 5)) r = (contour_index + 3) % 3 g = (contour_index + 2) % 3 b = (contour_index + 1) % 3 stroke(r, g, b) strokeWidth(4) line(pCenter, (p.x, p.y)) oval(p.x-5, p.y-5, 10, 10) translate(-x_offset, -self.y_offset) # draw wave forms wave_x = self.size[0] / num_frames * i + 5 * contour_index + 10 wave_forms[contour_index].append( ((wave_x, 0), (wave_x, distance(pCenter, (p.x, p.y)))) ) for a, b in wave_forms[contour_index]: line(a, b) restore() restore() if i < num_frames - 1: newPage() saveImage("~/Documents/AIFF_visualize_%s.pdf" % n) else: print "There is no font"
for weight in weigths: font_source = OpenFont("U+2194_Matriz.ufo", showUI=False) font_dest = NewFont() font_dest.info.familyName = family_name font_dest.info.styleName = "%s %s" % (behavior, weight) font_dest.info.fullName = "%s %s %s" % (family_name, behavior, weight) for font_source_glyph in font_source: # cria um glifo "temporario" work_glyph = font_source[font_source_glyph.name] # reparte e achata todos os segmentos de acordo com a distância flattenGlyph(work_glyph, flatten_distance) if th is True: thresholdGlyph(work_glyph, threshold_distance) # gera uma lista de pontos por contorno formatada em tuplas work_glyph_point_list = [] for contour in range(len(work_glyph.contours)): work_glyph_contour_point_list = [] for points in work_glyph[contour].points: # pega somente pontos dentro da curva if str(points.type) is not "offCurve": work_glyph_contour_point_list += [(points.x, points.y)] # work_glyph_contour_point_list += [(points.x+randint(0,200), points.y+randint(0,200))] work_glyph_point_list += [work_glyph_contour_point_list] # cria o espaço para o novo glifo na fonte destino
def exp_R(self, font, xHeight): # Calling the glyph R = font["R"] # Contours separation (internal, external) internal_level, external_level = self.contours_separation(R) # Flattening contours flattenGlyph(internal_level, 10) flattenGlyph(external_level, 10) # Filtering x values left_stem_x_values = self.filter_points(external_level, "x") right_stem_x_values = self.filter_points(internal_level, "x") # Left middle points, occurrences collection left_stem_x_values = self.occurDict(left_stem_x_values) right_stem_x_values = self.occurDict(right_stem_x_values) # Left middle points, reordering occurrences left_stem_x_values = sorted(left_stem_x_values.items(), key=itemgetter(1), reverse=True) right_stem_x_values = sorted(right_stem_x_values.items(), key=itemgetter(1), reverse=True) # Left middle point, x value left_middle_point = (left_stem_x_values[0][0] + right_stem_x_values[0][0]) / 2.0 # Right middle point left_bowl_x_values = self.filter_points(internal_level, "x") right_bowl_x_values = self.filter_points(external_level, "xy") # Right middle point, extreme internal left_extreme = max(left_bowl_x_values) # extreme superior right_bowl_x_values = sorted(right_bowl_x_values, key=itemgetter(1), reverse=True) extreme_superior = right_bowl_x_values[0][1] # Filtering the upper half of the glyph right_bowl_x_values = [item for item in right_bowl_x_values if item[1] >= extreme_superior / 2.0] # x values reordering right_bowl_x_values = sorted(right_bowl_x_values, key=itemgetter(0), reverse=True) # Bowl right extreme right_extreme = right_bowl_x_values[0][0] # Right middle point right_middle_point = (right_extreme + left_extreme) / 2.0 # 'R' expansion expansion_R = right_middle_point - left_middle_point # Visual check R_stats = R.getLayer("stats", clear=False) # Middle points self.rect(R_stats, left_middle_point, R.box[3] / 1.5, 2, 2) self.rect(R_stats, right_middle_point, R.box[3] / 1.5, 2, 2) # Extremes self.rect(R_stats, left_extreme, R.box[3] / 2.0, 2, 2) self.rect(R_stats, right_extreme, R.box[3] / 2.0, 2, 2) self.rect(R_stats, left_stem_x_values[0][0], R.box[3] / 2.0, 2, 2) self.rect(R_stats, right_stem_x_values[0][0], R.box[3] / 2.0, 2, 2) return round(expansion_R / xHeight, 4)
def contrast(self, font): # Calling the glyph o = font["o"] # Contours separation internal_level, external_level = self.contours_separation(o) # Flatting the level flattenGlyph(internal_level, 10) internal_points_number = len(internal_level[0]) # External contour length external_length = self.contourLength(external_level[0]) # External segment length d = external_length / internal_points_number # checked flattening flattenGlyph(external_level, d) # contour direction correction internal_level.correctDirection() external_level.correctDirection() # Correction starting points internal_level[0].autoStartSegment() external_level[0].autoStartSegment() # Contour condition if internal_level[0].clockwise == external_level[0].clockwise: pass else: print "There's an error!" # Checking the contour with less points if len(internal_level[0]) <= len(external_level[0]): len_min = len(internal_level[0]) elif len(internal_level[0]) > len(external_level[0]): len_min = len(external_level[0]) # Iteration over the number of contour points distances = [] for i in range(len_min - 1): # Points selection x1 = internal_level[0].points[i].x y1 = internal_level[0].points[i].y distances_detail = [] for l in range(-3, 4): # Estrarre solo quello più corto # Indice di controllo index = i + l if index >= len_min: index = index - len_min x2 = external_level[0].points[index].x y2 = external_level[0].points[index].y # distance between points (Pitagora) distanza = hypot((x1 - x2), (y1 - y2)) # Detail check distances_detail.append((((x1, y1), (x2, y2)), distanza)) # Reordering details list distances_detail = sorted(distances_detail, key=itemgetter(1)) # Collection of the shortest measure distances.append(distances_detail[0]) # Reordering values list distances = sorted(distances, key=itemgetter(1)) # Calling the shortest and the longest thickness shorter_thickness = distances[0][1] greater_thickness = distances[-1][1] # Contrast calculation contrast = shorter_thickness / greater_thickness # Slope shorter thickness calculation angle_min_thick = self.angle_segment(distances[0][0][0], distances[0][0][1]) # Visual check o_stats = o.getLayer("stats", clear=False) self.rect(o_stats, distances[0][0][0][0], distances[0][0][0][1], 2, 2) # shortest self.rect(o_stats, distances[0][0][1][0], distances[0][0][1][1], 2, 2) # shortest self.rect(o_stats, distances[-1][0][0][0], distances[-1][0][0][1], 2, 2) # longest self.rect(o_stats, distances[-1][0][1][0], distances[-1][0][1][1], 2, 2) # longest return round(contrast, 2), int(round(angle_min_thick, 0))
def _drawElements(self, glyph, color, distance, mode): assert mode == 'canvas' or mode == 'foreground' assert self.elementShape in SHAPE_OPTIONS if mode == 'foreground': phantomGlyph = RGlyph() for eachContour in glyph: for indexSegment, eachSegment in enumerate(eachContour): if indexSegment != len(eachContour) - 1: nextSegment = eachContour[indexSegment + 1] else: if eachContour.open is True: continue else: nextSegment = eachContour[0] pt1 = eachSegment.onCurve.x, eachSegment.onCurve.y pt4 = nextSegment.onCurve.x, nextSegment.onCurve.y if nextSegment.offCurve: pt2 = nextSegment.offCurve[0].x, nextSegment.offCurve[0].y pt3 = nextSegment.offCurve[1].x, nextSegment.offCurve[1].y else: pt2 = pt1 pt3 = pt4 pt1 = eachSegment.onCurve.x, eachSegment.onCurve.y pt4 = nextSegment.onCurve.x, nextSegment.onCurve.y if eachSegment.onCurve.naked().uniqueID in glyph.lib[PLUGIN_KEY] and \ nextSegment.onCurve.naked().uniqueID in glyph.lib[PLUGIN_KEY]: startLib = glyph.lib[PLUGIN_KEY][ eachSegment.onCurve.naked().uniqueID] endLib = glyph.lib[PLUGIN_KEY][ nextSegment.onCurve.naked().uniqueID] bezPoints = collectsPointsOnBezierCurveWithFixedDistance( pt1, pt2, pt3, pt4, distance) for indexBezPt, eachBezPt in enumerate(bezPoints): factor = indexBezPt / float(len(bezPoints)) width = lerp(startLib['width'], endLib['width'], factor) height = lerp(startLib['height'], endLib['height'], factor) angle = lerp(startLib['angle'], endLib['angle'], factor) if mode == 'canvas': save() fill(*color) translate(eachBezPt[0][0], eachBezPt[0][1]) rotate(angle) if self.elementShape == 'Oval': oval(-width / 2., -height / 2., width, height) else: rect(-width / 2., -height / 2., width, height) restore() else: matrix = Identity matrix = matrix.translate(eachBezPt[0][0], eachBezPt[0][1]) matrix = matrix.rotate(math.radians(angle)) if self.elementShape == 'Oval': robofabOval(phantomGlyph, 0, 0, width, height) else: robofabRect(phantomGlyph, 0, 0, width, height) phantomGlyph[len(phantomGlyph) - 1].transform(matrix) if mode == 'foreground': phantomGlyph.removeOverlap() flattenGlyph(phantomGlyph, 20) thresholdGlyph(phantomGlyph, 5) if version[0] == '2': glyph.getLayer('public.default', clear=True).appendGlyph(phantomGlyph, (0, 0)) else: glyph.getLayer('foreground', clear=True).appendGlyph(phantomGlyph, (0, 0))