Search code examples
haskellhaskell-diagrams

Haskell Diagrams: Why does text not have length or width?


I would like to create a text box that I can set to have a particular width and height. However, the text box that I create appears to not have a width and height in the first place. E.g. the following code:

main = do
  putStrLn $ show $ width $ myText
  putStrLn $ show $ height $ myText
  mainWith myText

myText :: Diagram B
myText = text "here" # lw 1 # fontSizeL 0.2 # fc grey # scaleX 1

results in a blank diagram (with no text), and prints "0.0" as the width and height of the text box:

ghc --make Main.hs && ./Main -o circle.svg -w 400
[1 of 1] Compiling Main             ( Main.hs, Main.o )
Linking Main ...
0.0
0.0

In order to get the text to appear it seem that I need to place it on top of something else. E.g. the following code:

main = do
  putStrLn $ show $ width $ myDiagram 
  putStrLn $ show $ height $ myDiagram
  mainWith myDiagram

myDiagram :: Diagram B
myDiagram = myText <> myBackground

myText :: Diagram B
myText = text "here" # lw 1 # fontSizeL 0.2 # fc grey # scaleX 1

myBackground :: Diagram B
myBackground = rect 1 1 # fc black

produces the grey text within a black background as expected.


Why does the text box not have a size?

How can I set the length and width of a text box to a certain value?


Solution

  • Why does the text box not have a size?

    Because text handling is not only highly dependent on the backend used to render the diagrams (cf. the User's Guide) but also potentially dependent on how fonts are configured in the system used to run the program.

    How can I set the length and width of a text box to a certain value?

    1. Use text handling functions provided by your chosen backend, if they exist. For instance, diagrams-cairo provides functions that use Pango to render text on its own, though with the significant annoyance of them being IO functions, as they need to query font information from the system.

    2. Use SVGFonts to stroke the text independently of the backend. There are a few inconveniences with this approach as well (limited choice of fonts unless you follow the instructions in the documentation to convert your chosen font to the SVGFonts format yourself; fonts with large sets of characters might lead to a small but noticeable delay when they are first used by your program, as they have to go through an initial processing), but at least you don't have to bother with IO or backend-specific quirks.