In case anyone's following this thread: over on RoboFont's Discord, thanks to Wim asking we determined that the issue had mainly to do with a bug in a pre-release version of DB I was using; using v3.130 cleared things up.
Posts made by MauriceMeilleur
-
RE: Defining lineHeight and first baseline: status?
-
RE: Defining lineHeight and first baseline: status?
@jo I doubt it's a UPM issue … I was noticing the problem before I went back and remade the fonts (I did that to solve a different problem, namely to fix problems caused by RoboFont rounding floating-point coordinates in ways that threw off alignment). And I'm getting weird behavior with other fonts, as for example see above in response to Wim's post and using his code …
-
RE: Defining lineHeight and first baseline: status?
@monomonnik said in Defining lineHeight and first baseline: status?:
source = 'lestextessociologiques'
fSize = 90
array = FormattedString()
ft = 'Helvetica'
lh_min = 100
lh_max = 200
lh_step = 10temp = FormattedString()
for lh in range(lh_min, lh_max, lh_step):
temp.append(source, font=ft, fontSize=fSize, lineHeight=lh, align='center')
temp.append('\n')
array.append(temp)newPage()
with savedState():
fill(1)
rect(0, 0, width(), height())textBox(array, (0, 0, width(), height()))
fill(None); stroke(1, 0, 0)
y = height()
for lh in range(lh_min, lh_max, lh_step):
y -= lh
line((0, y), (width(), y))saveImage('~/Desktop/baseline_test.png')
Well, this is interesting: when I run that code, here's the output I get:
-
RE: Defining lineHeight and first baseline: status?
Hi, Jo—
Sorry, I've packed a lot into my question. Here's my initial problem:
For the book I'm writing on Jurriaan Schrofer's constructed scripts, I'm designing a series of variable fonts for the diagrams and reconstructions. To recreate this cover Schrofer used for a series of sociology texts I've created a font with two variation axes, height and width, both of which change the ratio of stroke to counter. The strokes or counters are larger depending on whether the value of the axis in question is positive or negative. The height axis is defined such that the glyphs are at their tallest and occupy the entire glyphspace minus top/bottom spaces when the ratio of horizontal strokes to counters is 10:1. They're at their shortest when the ratio is 1:1. Sidebearings are constant and equal to .5 the stroke/counter width at 1:1. (If it helps: I'm using 550upm to keep integer coordinates for all my masters; descender is -5; x-, cap-, and ascender are 545; LSB/RSB are both 5.)
What I'd like to do is keep fontSize constant and vary the lineHeight from line to line based on the calculated height of the drawn glyphs in each line according to the setting of the height axis. (The heights will all be less than the nominal fontSize because the glyphs never need to be drawn to their maximum height for this layout.) The linespacings are easy enough to calculate, but for some reason I can't feed them as lineHeights to a FormattedString and get linespacing I can make any sense of.
So for example: here I have a textBox the dimensions of the canvas and the height axis in the first line set to my intended max ratio 3.5:1 (strokes/counters), except for the last glyph S with the axis set to 10:1 for reference, and the lineHeight set to the fontSize. The first baseline is exactly where I'd expect it to be; the first red line from the top is the fontSize distance from the top of the textBox. But the next baseline, for a line of type with identical linespacing to the first line (fontSize), is … not. The second red line shows where the next baseline should be (twice the fontSize from the top of the textBox), and you can see where DrawBot is actually drawing the type.
It gets weirder: If I calculate what the linespacing for the first line should be and give it to both lines of text in the FormattedString, here's what I get. The two blue lines are where the lines of type should be, the red lines are from the first example for reference.
You can see the lines are moved up from the first example, but not by nearly enough, and the lines are much farther apart than their specified linespacing.
Here's the code (I can share the font too if needed):
source = 'lestextessociologiques' fSize = 550 array = FormattedString() ft = '/Users/meilleur/Desktop/Variable/schrofer_02_textes-VF.ttf' u = fSize/55 lHAdj = (5 * u) + (3.5 * 5 * u) temp = FormattedString() for index, char in enumerate(source): temp.append(char, font=ft, fontSize=fSize, lineHeight=lHAdj, align='center', fontVariations={'wdth': -5.5 + index * .5, 'hght': 2.5 if index < (len(source) - 1) else 9}) #9 is max height, 10:1 stroke:counter array.append(temp) array.append('\n') temp = FormattedString() for index, char in enumerate(source): temp.append(char, font=ft, fontSize=fSize, lineHeight =lHAdj, align='center', fontVariations={'wdth': -5.5 + index * .5, 'hght': 2.5}) array.append(temp) # array.append('\n') newPage(2000, 2000) with savedState(): fill(1) rect(0, 0, width(), height()) textBox(array, (0, 0, width(), height())) fill(None); stroke(1, 0, 0) line((0, height() - fSize), (width(), height() - fSize)) line((0, height() - 2 * fSize), (width(), height() - 2 * fSize)) stroke(0, 0, 1) line((0, height() - lHAdj), (width(), height() - lHAdj)) line((0, height() - 2 * lHAdj), (width(), height() - 2 * lHAdj)) stroke(0); strokeWidth(2) rect(0, 0, width(), height()) saveImage('~/Desktop/baseline_test.png')
-
Defining lineHeight and first baseline: status?
I've reviewed everything I could find that people have posted here and on the DB GitHub repo about the difficulties with defining lineHeight and first baselines, and the conversations/threads feel either abortive or circular/self-referential—so let me ask this outright: Is it (still) impossible to specify exactly the lineHeight of a FormattedString (in a given line of text, across multiple lines, from one line to the next) and the position of the baseline of the first line of text in a textBox? Or, have (precise, reliable) solutions been found to these problems?
Even fixes that have to be tailored to a given font that still allow me to set type algorithmically would be welcome. I'm going to have a lot of diagrams and specimens to make soon, and I'd really hate to drag InDesign and manual typesetting back into my workflow any more than I absolutely have to …
-
RE: Can I use use areaAverage() to analyze an actual image?
Thanks—I guess this makes sense, but the docs suggest that it's possible to add arguments to specify an 'area of interest' (https://www.drawbot.com/content/image/imageObject.html#drawBot.context.tools.imageObject.ImageObject.areaAverage). In any case I found a workaround by getting creative with sampling pixels in the image.
-
Can I use use areaAverage() to analyze an actual image?
For an upcoming course—and for my book on Jurriaan Schrofer—I'm trying to recreate the process some of Schrofer's former colleagues at Total Design used in 1987 to rasterize a photo of him with various weights of one of his script designs.
It seems like I should be able to use areaAverage() to scan a grid of areas in a given image, get the average color of each area, and then use that information to choose an appropriate weight of the glyph that will act as a pixel for that area in the generated image. That is, I'll get a 1px image with that average color—which I can presumably then extract the color information from to use further?
But: the output of my code suggests that areaAverage() isn't seeing the image in the ImageObject. I'm saving the images in an array to analyze them one at a time; here's the code:
path = '/Users/meilleur/Desktop/maurice-meilleur-web-600p_hi.png' w, h = imageSize(path) newPage(w, h) im = ImageObject() with im: size(w, h) image(path, (0, 0)) image(im, (0, 0)) res = 60 s = w/res areas = [] startX = 0; startY = 0 for row in range(res): y = startY + row * s temp = [] for col in range(res): x = startX + col * s temp.append(im.areaAverage((x, y, s, s))) areas.append(temp) print(imagePixelColor(areas[0][0], (0, 0)))
And this throws an error:
Traceback (most recent call last):
File "schrofer_illegible_raster.py", line 23, in <module>
File "/Applications/DrawBot.app/Contents/Resources/lib/python3.9/drawBot/drawBotDrawingTools.py", line 2020, in imagePixelColor
AttributeError: 'NoneType' object has no attribute 'startswith'Obviously I'm missing something here …
-
saveImage() .mp4 options: Looping?
It looks to my untutored eye like the ffmpeg codec supports looping—could that be included as an optional argument in saveImage() for .mp4?
-
RE: The promise and perils of expandStroke()
Update: this problem appears to be an artifact of combining and expanding two+ strokes in DrawBot. I only see this at corners where two adjacent closed paths are combined and expanded.
-
The promise and perils of expandStroke()
Welp. Thought I’d skate through using expandStroke() for the Schrofer constructed script I’m currently digitizing in RoboFont, but I think I’ll be rolling my own instead.
This doesn't happen consistently, by the way:
-
RE: Am I missing something from expandStroke() documentation?
@monomonnik Oh, I see—I was treating it like a method. Thanks.
-
Am I missing something from expandStroke() documentation?
Going to post this here under the assumption it's not a bug, it's me: am I missing anything in the documentation for expandStroke()? Because I can't seem to get it to work for me:
-
RE: FontTools, probably a simple question
@frederik Oh, I see—I just needed to import (from) the right submodule. Thanks!
-
FontTools, probably a simple question
I'd like to use the FontTools methods for finding arc length and finding points along a curve at https://github.com/fonttools/fonttools/blob/main/Lib/fontTools/misc/bezierTools.py#L98. I can import the fontTools module, but I don't seem to be able to use methods like calcCubicArcLength(). I guess I could just pull code out of the repo, but I'd rather use the functions from the module. What am I missing?
-
.svg resolution/units options for saveImage()
Is it possible to add units and resolution as options for .svg export in saveImage()? I have a very niche reason for asking: I want to use exported .svg files with a plotter, and it might make the files easier to use if the units/resolution (effectively, scale) information in the .svg file.
Specifically, I want to plot .svg outputs with an AxiDraw, and I'm having trouble convincing Inkscape that the files should be treated as 72dpi rather than stubbornly insisting (1) that they are sized in pixels, not DTP, and (2) that it should treat them as if they're 96ppi.
-
Gaussian blur moves object when applied in different places in the code?
Why does applying a Gaussian blur in different places in the code move the image it applies to? Example code, output, revised code putting the blur call before the 1st image, output.
size(550, 300) # initiate a new image object im = ImageObject() # draw in the image # the 'with' statement will create a custom context # only drawing in the image object with im: # set a size for the image size(200, 200) # draw something fill(1, 0, 0) rect(0, 0, width(), height()) fill(1) fontSize(30) text("Hello World", (10, 10)) # draw in the image in the main context image(im, (10, 50)) # apply some filters im.gaussianBlur() # get the offset (with a blur this will be negative) x, y = im.offset() # draw in the image in the main context image(im, (300+x, 50+y))
yields:
size(550, 300) # initiate a new image object im = ImageObject() # draw in the image # the 'with' statement will create a custom context # only drawing in the image object with im: # set a size for the image size(200, 200) # draw something fill(1, 0, 0) rect(0, 0, width(), height()) fill(1) fontSize(30) text("Hello World", (10, 10)) # apply some filters im.gaussianBlur() # draw in the image in the main context image(im, (10, 50)) # get the offset (with a blur this will be negative) x, y = im.offset() # draw in the image in the main context image(im, (300+x, 50+y))
yields:
-
RE: drawBot.misc.DrawBotError: No image found at http:...
@frederik https://www.drawbot.com/_/downloads/en/stable/pdf/, and my bad: I was using an old version of the documentation (3.121). I see the 3.126 version has a working URL. (The line break is breaking the link in the pdf, though.)
-
RE: drawBot.misc.DrawBotError: No image found at http:...
Ran into this same problem—@gferreira's updated URL works, but someone should update the DB pdf documentation for image(), etc. to include it and @frederik's detail about a direct link to image data.