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?
-
Calling
RFont(showInterface=False)
in DrawBot will create a new font object, a new UFO. You can add glyph to the font object by calling `myFont.newGlyph("a"), it will return the glyph object.If you wish to open an existing ufo you can call:
RFont(pathToUfo, showInterface=False)
and get glyph data withmyExistingFont["a"]
(if the ufo contains a glyph).hope this helps!
good luck!
-
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)
-
hi @michelangelo, just a small note:
myFont.newGlyph(char)
RFont.newGlyph()
takes a glyph name, not a unicode character.cheers!
-
mmm, maybe you have to explain what you would like to achieve?
fontParts
is a library to read and write and manipulate ufo data.DrawBot callback
font("Helvetica")
,fontSize(10)
will set attributes needed while type setting some text.With
fontParts
you have access to spacing:glyph.width
and kerning in thefont.kerning
object. I would not encourage you to build a type setter
-
How does drawBot know when to use the kerning pairs for [AA], [AW]?
in your example Helvetica is an installed font in binary format, you can use it to set text etc. while
RFont
andRGlyph
are normally used to edit source fonts in UFO format.if you want to access and manipulate glyphs of an installed font, you can do it using the
BezierPath
object:from fontPens.flattenPen import FlattenPen TEXT = 'abcd' FONTSIZE = 300 size(800, 300) translate(40, 40) fontSize(FONTSIZE) for char in TEXT: # get bezier shape for character src = BezierPath() src.text(char, (0, 0), fontSize=FONTSIZE) # modify shape using a pen dst = BezierPath() pen = FlattenPen(dst, approximateSegmentLength=60) src.drawToPen(pen) # draw original shape stroke(None) fill(0.8) drawPath(src) # draw modified shape fill(None) stroke(1, 0, 0) drawPath(dst) # get advance width advance = textSize(char)[0] # move to next character translate(advance, 0)
this example uses a pen to transform the glyph, but you can also do it using your own functions.
hope this makes sense!
-
@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...
-
@michelangelo
textSize()
uses the current graphics state to measure some text, so in order get the advance widths for your font, you need to set it first:FONTNAME = 'someFont' font(FONTNAME) # <-- set the font before measuring for char in TEXT: src.text(char, (0, 0), font=FONTNAME, fontSize=FONTSIZE) drawPath(src) advance = textSize(char)[0] # measure using the current font
cheers!
-
@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!