here's a slightly better version of the fit-text-in-a-rect code.
still, as you wil see, sometimes the last line of the text flows out of the box.
any ideas?
size(600, 600) grid = ximport("grid") # so that we can use the new text.fit_fontsize method font("Helvetica") myX = 50 myY = -50 var("myW", NUMBER, 135, 10, 600) # desired box width var("myH", NUMBER, 83, 10, 600)# desired box height myString = "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit last line etc etc..." fSize = grid.text.fit_fontsize(myString, myW, myH) fontsize(fSize) tp = textpath(myString, x=myX, y=myY, width=myW, height=myH) (tpX, tpY), (tpW, tpH) = tp.bounds #print tpX, tpY, tpW, tpH deltaY = tpY - myY # gray rect from textpath.bounds coordinates nofill() stroke(0, 0.4) rect(tpX, -tpY, tpW, tpH) # red rect from textmetrics coordinates stroke(1, 0, 0, 0.4) rect(myX, -myY-deltaY, textwidth(myString, width=myW), textheight(myString, width=myW)-deltaY) fill(0) #align(RIGHT) text(myString, x=tpX, y=-tpY-deltaY, width=tpW, height=tpH)
Hi Giorgio,
Some tough questions :-)
First of all, as you mention there is a difference between textmetrics() and path.bounds. The bounds is the box that fits exactly around the given path, whereas texmetrics is the hidden paragraph box - which is more complex do to spacing etc.
Second, the grid.text.fit_fontsize() matches text size to the width of a given box. What you want is vertical fitting as well, which is more difficult. But we can start from fit_fontsize() which is quite a solid algorithm. The most elegant solution I've found so far is to then do additional lineheight() tweaking:
grid = ximport("grid") txt = "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..." x = 40 y = 70 var("w", NUMBER, 200, 50, 400) var("h", NUMBER, 200, 50, 400) f = grid.text.fit_fontsize(txt, w+10, h) fontsize(f) # Increase line spacing until the last line touches the bottom of the box. for i in range(100): if textheight(txt, w+10) < h: lineheight(lineheight()+0.01) else: break fill(0) text(txt, x, y, width=w+10) rect(x, y-fontsize(), w, h, fill=None, stroke=0)Last, notice that sometimes I use width+10 instead of just width to get the dimensions exactly right. This is workaround for a bug in NodeBox that needs fixing. We've only recently discovered it when writing the Grid library.
Hello Tom,
thanks for the answers! I'll posto soon the result of the experiment I'm working on.
Hey Giorgio,
I've added a text.fit_lineheight() to the latest release of the grid library, based on the code above.
How to perfectly fit text in a box
Posted by Giorgio O. on Jul 26, 2008hello everybody,
as you can see from the output, there's a problem at the end of the text box: one or more lines (depending on font size) are 'lost' drawing the text box.I'd love some help in trying to find a way to perfectly fit some text in a rectangular box, in order to get as little margin as possible.
'Perfectly' here means to get the real vertical size of the text box.
If I have a string, I can get the estimate of the coordinates of the text bounds in a couple of ways, but neither is really satisfying.
I've tried so far:
a) using textheight & textwidth
b) using the textpath.bounds
they do return different values.
my test code:
ciao
G