@gferreira Thank you! That is much clearer now. I found that in my example I have a lot of transformations and somewhere it gets weird again, but on its own it works!
Posts made by michelangelo
-
RE: Set Rfont to some font and access its glyph methods
-
RE: Set Rfont to some font and access its glyph methods
@gferreira That seems important! Thank you!
@frederik No, I do not want to make my typesetter, definitely. Thanks for the heads up. What Gustavo explained is what I am talking about...This is exactly what I need. However, my font doesn't react normally to it... The same code with the same arguments, only different fonts:
for char in TEXT: src.text(char, (0, 0), font='someFont', fontSize=FONTSIZE) drawPath(src) advance = textSize(char)[0]
But if I typeset it in another way, it works:
font('someFont', fontSize=FONTSIZE) text(TEXT, (0, 0))
That's why I am confused...
-
RE: Set Rfont to some font and access its glyph methods
Thank you, @frederik. That's exactly what I was wondering! I am trying to access the side bearings but what is the method for that (leftMargin, rightMargin)?
If I use the drawBot text():
font('Helvetica', 200) txt = 'ABCW' text(txt, (0,0))
The spacing is perfectly rendered from the font. How does drawBot know when to use the kerning pairs for [AA], [AW]?
If I manipulate the characters one by one and then render them, how can I use the existing font bearings to maintain proper spacing?
I end up with this kind of nonsense:
def drawText(txt, x, y, fSize): for char in txt, range(len(txt))): aWidth = fSize * 0.6 * i if char =="A": aWidth += i * 40 # + (glyph.leftMargin?) if char =="B": aWidth += i * 36 ... renderChar(char, x + aWidth, y, fSize)
-
Set Rfont to some font and access its glyph methods
Hello guys,
I was wondering how Rfont and RGlyph work? I can set amyFont.newGlyph(char)
but I am missing something.from fontParts.world import RFont, RGlyph # create a font object myFont = RFont(showInterface=False) fontName = "LucidaGrande" char = 'A' glyph = myFont.newGlyph(char) print(glyph)
I get, as expected:
<RGlyph 'A' ('public.default') at 4470687248>
but then the glyph is empty if I:
print(glyph.isEmpty())
Usually you would do
glyph = CurrentGlyph()
but I am working in drawBot. Can I just set this glyph to a typeface I specify and still get access to all the methods of a RGlyph() object?
-
RE: UI help
Hello @frederik,
thank you for sheding some light on the issue. Maybe I will try the DrawBot package.Sorry for the confusion about the example, I meant this which is from the official documentation of Vanilla. I also understand now that a
print()
command prints in a specified window (I guess) and not the console.Thanks! It is exciting to see all sliders and buttons
-
UI help
Hello there,
I have a question about some UI within drawbot. I used the standard Variable[] but it is not really working for my purpose.
In short: I have a string ('SOME TEXT') that renders each letter, but there are multiple methods that can be chosen for each of them.
Here, I am just hardcoding the dictionary 'options' for each character...
If I use the default UI from Drawbot I can render the text
but I also want to show under it, based on the string, a multiple choice for each letter:
I saw that the vanilla library is meant for this, but what approach could I take to enter the string and based on it to render a dictionary which can be modified by the user? And btw these examples from RoboFont don't print anything, not sure if they work on my machine. No errors but I am not sure what I should do.
Thanks a lot!
-
RE: Manipulating points
Great, that makes sense. Is it also possible in DrawBot directly? I would like to animate it with other letters later.
-
RE: Manipulating points
Hi @frederik, thanks, I got RoboFont now and labelled them, but how can I references them.
What method could find the labelled points in an array of points?
If I use:
for points in srcShape.points: print(points)
I get all points (x, y), but they have no 'label' attribute.
-
Manipulating points
Hello guys,
I want to try some point manipulation in DrawBot. I have used bezier paths before but it seems like it is very unclear how to start it all.In short I have a drawn font and I want to:
- Load a letter or a string into Drawbot (or work directly in Glyphs)
- Select the specific points I want to manipulate
- Move them around while keeping the curve smooth
Here I attach a gif of what I have in mind as the end result:
β Can I label specific points from Glyphs to access them easily later?
β Perhaps there is already something similar asked in the forum but I didn't find it. Can you reference it here?thank you!
-
Exporting a variable font from DrawBot
Hello all,
I am working on a variable font that wasn't supposed to be variable but hey, why not? We drew a font and this is then imported in DrawBot to be "messed up". @justvanrossum helped me set it up already and I have a few examples.Original:
Slightly modified:
Heavily modified:
Modification is randomly applied to each character:
Now the "variation" only happens in this intensity of messing it up. I am interested how I can let the user create this intensity in InDesign or other software, instead of it being hard-coded.
Here is my code:
from fontParts.world import RFont from fontTools.agl import UV2AGL import math import random from defcon import Font # create a font object myFont = RFont(showInterface=False) # some default example values myFont.info.descender=-250 myFont.info.xHeight=500 myFont.info.ascender=750 myFont.info.capHeight=750 myFont.info.unitsPerEm=1000 myFont.info.unitsPerEm=1000 myFont.info.familyName="Bogota" Variable([ dict(name="offsetValue", ui="Slider", args=dict( value=0.0, minValue=-2.0, maxValue=2.0)), dict(name="Save_As_UFO", ui="CheckBox"), dict(name="Reset_Offset", ui="CheckBox"), ], globals()) if Reset_Offset == True: offsetValue = 0.0 fontName = "PanamaDisplay-Regular.otf" charSet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9",".",",","!","?","[","]","-","β",'β','β','β','β','"',"'"] def calculateDistance(pt1, pt2): x1, y1 = pt1 x2, y2 = pt2 dist = math.sqrt((x2 - x1)**2 + (y2 - y1)**2) return dist def calculateHandles(pt1, pt2): x1, y1 = pt1 x2, y2 = pt2 dx = x2 - x1 dy = y2 - y1 offset = offsetValue # vector (y, -x) is perpendicular to vector (x, y): handleOffsetX = offset * dy handleOffsetY = -offset * dx h1Pos = 0.25 h2Pos = 0.75 h1x = x1 + h1Pos * dx + handleOffsetX h1y = y1 + h1Pos * dy + handleOffsetY h2x = x1 + h2Pos * dx + handleOffsetX h2y = y1 + h2Pos * dy + handleOffsetY return (h1x, h1y), (h2x, h2y) def extractContours(bez): contours = [] for cont in bez.contours: poly = [] for seg in cont: for pt in seg: poly.append(pt) contours.append(poly) return contours def saveAsUFO(path, char): # get unicode for character uni = ord(char) # get glyph name for unicode glyphName = UV2AGL.get(uni) # create a glyph object myGlyph = myFont.newGlyph(glyphName) # set unicode myGlyph.unicode = uni # get the pen pen = myGlyph.getPen() font(fontName) fontSize(1000) w, h = textSize(char) myGlyph.width = w # draw path into glyph with pen path.drawToPen(pen) def drawContours(contours, char): bez = BezierPath() for contour in contours: prevPoint = contour[0] bez.moveTo(prevPoint) for pt in contour[1:]: h1, h2 = calculateHandles(prevPoint, pt) bez.curveTo(h1, h2, pt) # bez.lineTo(pt) prevPoint = pt bez.closePath() drawPath(bez) saveAsUFO(bez, char) # Convert the letter into Bezier Path for i in range(len(charSet)): newPage(1000, 1000) # offsetValue = random.uniform(-0.5, 0.5) bez = BezierPath() bez.text(charSet[i], font=fontName, fontSize=840) xMin, yMin, xMax, yMax = bez.bounds() cx = (xMin + xMax) / 6 cy = 0 bez.translate(cx, cy) # drawPath(bez) contours = extractContours(bez) # print(contours) drawContours(contours, charSet[i]) if Save_As_UFO: # save the ufo myFont.save("Bogota.ufo")
-
RE: Exporting a .ufo file with fontParts doesn't create a valid file
@frederik Thank you, I managed! It works smoothly nowβI was just missing the
font.familyName
but after adding this, it works.I was wondering if I can do it inside DrawBot right away? I tried to import
fontmake
orufo2ft
as a module but it doesn't work. Could it be that pip doesn't install it globally and DrawBot cannot find itβif that's the case where should I put it so DrawBot can see it? -
RE: Exporting a .ufo file with fontParts doesn't create a valid file
@frederik Thank you, Frederik. I tried both ufo2fdk I don't how to use, the documentation is a bit confusing for me.
Anyways, with fontParts I ran the script but it gave me
KeyError: 'unitsPerEm'
Is it related to my font or to fontParts script in your opinion?
-
RE: Exporting a .ufo file with fontParts doesn't create a valid file
@frederik Thank you! I don't exactly know how to use the ufo2fdk, but I will try.
-
RE: Exporting a .ufo file with fontParts doesn't create a valid file
@frederik maybe you can help me with that one?
-
RE: stuck in the code
Hello @habakuk,
first of all you should definitely post your code. How else are we supposed to help you? If there is a lot of "mess" (commented or unusable code), clean it up before posting.Now, it seems like you just want to play around. Start following the basics shapes (primitives), paths, text, images and you will learn a lot. It's super nice that you already started doing your own stuff, but it will be good to know what's already there.
I am saying this because you can probably figure how to make two opposing paths from there.
Here is a short sample of what I think I understand from your post.
# Define a function to draw your shape def Blob(offset): # Let's make a Bezier Path shape bez = BezierPath() bez.moveTo((100 + offset, 100 + offset * 0.1)) bez.curveTo((60 + offset, 64 + 0.2 * offset), (-4, 136), (72 + offset * 0.5, 170 + offset * 0.5)) bez.curveTo((74 + offset, 92 + 0.1 * offset), (110, 264), (126 + offset * 0.8, 114 + offset * 0.3)) bez.closePath() # Here I make Another shape, but it's going the opposite direction bez.moveTo((110, 140)) bez.lineTo((64, 136)) bez.lineTo((68, 106)) bez.lineTo((106, 114)) bez.closePath() # Drawing the shape here drawPath(bez) numFrames = 60 for i in range(numFrames): t = i / numFrames newPage(1000, 1000) fill(1) rect(0, 0, 1000, 1000) scale(4) fill(0) # The function takes an argument "offset" to create the movement offset = sin(t * 100) * 10 print(offset) Blob(offset) saveImage("~/Desktop/blob.gif")
-
RE: which fonts compatible with variations?
Hello @geancarle,
I searched Wikipedia for the Skia typeface and found out we are dealing with GX Variations. This article on AxisPraxis (very good resource for variable fonts btw) sheds some light on the technology: https://www.axis-praxis.org/blog/2016-11-14/6/article-gx-variations-a-typographic-revivalI suppose you can find more by googling the term or check this: http://www.gxfanclub.com/gxfonts.html
Otherwise, we are just talking about Variable fonts and you can find many open-source on AxisPraxis or somewhere else on the web.
Good luck!
-
RE: Exporting a .ufo file with fontParts doesn't create a valid file
@gferreira Thanks a lot. Everything works now!
Follow-up questions will be:
-
As I have an offsetValue to tweak the bending of the letters, would it be simple to do all of this inside Glyphs? This way I can open Glyphs, tweak it as much as I want and export right away as .OTF.
-
Or how can I export an .OTF directly from DrawBot? I tried with myFont.generate() but something went wrong...
formats = { 'OpenType-CFF (.otf)' : 'otfcff', 'OpenType-TTF (.ttf)' : 'otfttf', 'PostScript (.pfa)' : 'pctype1ascii' } # save the ufo if ExportUFO == True: myFont.save("Bogota.ufo") for format in formats.keys(): print('Generating %s font...' % format) print(myFont.generate(formats[format])) --------------------------------------------- Generating OpenType-CFF (.otf) font... Traceback (most recent call last): File "Bogota5.py", line 126, in <module> File "/Applications/DrawBot.app/Contents/Resources/lib/python3.6/fontParts/base/font.py", line 362, in generate File "/Applications/DrawBot.app/Contents/Resources/lib/python3.6/fontParts/base/font.py", line 397, in _generate File "/Applications/DrawBot.app/Contents/Resources/lib/python3.6/fontParts/base/base.py", line 232, in raiseNotImplementedError NotImplementedError: The RFont subclass does not implement this method.
-
-
Exporting a .ufo file with fontParts doesn't create a valid file
Hello there,
Frederik helped me a few months ago and using his script, I managed to save shapes as glyphs in a .UFO file but when I open them they have:
-
no width (I probably need to specify this when saving but I didn't know where);
-
you can't type with them (in Glyphs at least). I suspect the unicode names for each glyph are not specified well enough.
Everything happens in saveAsUFO(), where "bez" is my vector shape and "char" is specifying which glyph I want this shape to be saved in.
from fontParts.world import RFont import math # create a font object myFont = RFont(showInterface=False) font = "LucidaGrande" charSet = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9",".",",","!","?","[","]","-","β",'β','β','β','β','"',"'"] def calculateDistance(pt1, pt2): x1, y1 = pt1 x2, y2 = pt2 dist = math.sqrt((x2 - x1)**2 + (y2 - y1)**2) return dist def calculateHandles(pt1, pt2): x1, y1 = pt1 x2, y2 = pt2 dx = x2 - x1 dy = y2 - y1 offset = -0.2 # vector (y, -x) is perpendicular to vector (x, y): handleOffsetX = offset * dy handleOffsetY = -offset * dx h1Pos = 0.25 h2Pos = 0.75 h1x = x1 + h1Pos * dx + handleOffsetX h1y = y1 + h1Pos * dy + handleOffsetY h2x = x1 + h2Pos * dx + handleOffsetX h2y = y1 + h2Pos * dy + handleOffsetY return (h1x, h1y), (h2x, h2y) def extractContours(bez): contours = [] for cont in bez.contours: poly = [] for seg in cont: for pt in seg: poly.append(pt) contours.append(poly) return contours def saveAsUFO(path, char): # create a glyph object myGlyph = myFont.newGlyph(char) # get the pen myChar = myGlyph.getPen() path.drawToPen(myChar) def drawContours(contours, char): bez = BezierPath() for contour in contours: prevPoint = contour[0] bez.moveTo(prevPoint) for pt in contour[1:]: h1, h2 = calculateHandles(prevPoint, pt) bez.curveTo(h1, h2, pt) # bez.lineTo(pt) prevPoint = pt bez.closePath() drawPath(bez) saveAsUFO(bez, char) # Convert the letter into Bezier Path for i in range(len(charSet)): newPage(1000, 1000) bez = BezierPath() bez.text(charSet[i], font=font, fontSize=840) xMin, yMin, xMax, yMax = bez.bounds() cx = (xMin + xMax) / 6 cy = (yMin + yMax) / 2 bez.translate(cx, cy) contours = extractContours(bez) drawContours(contours, charSet[i]) # save the ufo # myFont.save("Bogota.ufo")
-