design question/font metrics
Gery Debongnie <gery.debongnie <at> gmail.com>
2010-06-01 14:30:31 GMT
Dear Haskell-Cafe list,
Since I am learning Haskell, I decided to try to do a real program, to
practice and give me some experience. I choose to do a basic
typesetting program (like TeX/LaTeX). Now, obviously, such a program
needs to manipulate font objects, and in particular, font metrics.
Basically, I would like some function like this :
stringWidth :: Font -> String -> Double
charWidth :: Font -> Char -> Double
which take some appropriate font type, string or char, and gives me a
width (also height) in some given unit. I'd like it to take into
account appropriate kerning.
Question 1 :
Now, I may be missing something, but a quick search on Google/Hackage
didn't yield anything. Is there an existing package, or any nice and
simple way to deal with that problem?
Question 2 :
In case the answer to the previous question is negative, I guess I
will need to do it myself, the old-fashioned way. Now, this is where
I have a design question. The thing is that font metrics information
are encoded into some file (either .tfm or .pl files, for TeX fonts),
so my function stringWidth will need to read a file, which is, gasp,
an IO operation. Therefore, its type will be something like
stringWidth :: Font -> String -> IO Double
and it will "infect" pretty much everything else. It doesn't sound
really appealing, so I'd like your opinions on this subject. To start
the conversation, here are the solutions that I have in mind, so far :
1. well, do nothing, and let IO infect everything.
2. use unsafePerformIO to get rid of IO. (I am weary to do this,
since I am a newbie, and I don't really want to start using that
function everywhere... However, in this case, it looks kinda
3. Perform a reading of the font metrics file in the main program, put
the results into some FontMetrics object, and give that to stringWidth
:: FontMetrics -> Font -> String -> Double. Pros : allow me to avoid
problems of solution 1 and 2, cons : it doesn't sound right for the
main program to have to do this, it should be confined into a Font
Any other ideas, suggestions?