SVG-Fonts-0.4 released on Hackage

This library has been laying around in an unusable state on my harddrive for a long time, but now it is finally good enough to be used. In contrast to a lot of graphics libraries on Hackage it is not a binding. That means there were a lot of algorithms that had to be implemented. Although Haskell is often propagated as a language to write correct programs, algorithmic errors are as common as in other languages, because they cannot be catched by the type system. Debug.Trace, debugging with ghci is no alternative because they have no visual output and a list of hundred of floats is not helpful. In the future I plan to have a visual debugger for this.

But it works now. The interface should be easy to integrate into other libraries. Take a look at the following example:

main = do
  args <- getArgs
  let str = if null args then "Haskell" else head args
      resolution = (300, 300)
-- mode: INSIDE_V1_V2: the string is inside v1 v2 boundaries (height/length-relation not kept)
-- mode: INSIDE_V1: stay inside v1 boundary, size of v2 adjusted to height/length-relation
-- mode: INSIDE_V2: stay inside v2 boundary, size of v1 adjusted to height/length-relation
      mode = INSIDE_V2
-- spacing: MONO: Use mono spacing between glyphs
--          HADV: Every glyph has a unique constant horiz. advance
--          KERN: Same as HADV but sometimes overridden by kerning: i.e. the horizontal advance
--                in "VV" is bigger than in "VA"
      spacing = HADV
      gaw = makeOutlMap "../../../src/Test/GirlsareWeird.svg" resolution
      lin = makeOutlMap "../../../src/Test/LinLibertine.svg" resolution
      o = (0,0,1.1) -- origin
      v1 = (5,0,0) -- direction of char-advance
      v2 = (0,0,-1) -- height direction
      v3 = (0,0.2,0) -- extrusion

      f :: String -> [String]  -- assigning a property to every character by a unique string
      f str = replicate (length str) "p"
                              -- data CharProp = Prop (FontData, OutlineMap) String Textured
      prop :: Map.Map String CharProp
      prop = Map.fromList [("p", Prop lin "to3d" False)]
      -- transformation of a Geoemtry Node (i.e. triangulation)
      transf :: Map.Map String (Geometry -> Geometry)
      transf = Map.fromList [("to3d", to3d)]
      -- to3d: not the perfect solution since some points are generated twice
      to3d geom = ( ((extrude (0,0.1,0)).deleteHoles) geom ) `atop`
                    ( tri (translate (0,0.1,0) geom) )
      tri = (triangulate ketTri).deleteHoles

      tex = makeTexMap resolution prop transf
      node = displayString str "node" resolution prop transf mode spacing o v1 v2 f tex

  genCollada (lightedScene node) emptyAnim
  putStrLn "Collada File generated"

Line 30 shows that a integration into a drawing combinator library seems to be reasonable. I am a little bit proud that this library is lot smaller than freetype2 (something around 100KB against 4000KB)
and the only things that it cannot do (yet!) is Rastered Images, Autohinting, Unicode, and the big amount of file formats supported by freetype2.
Another difference is that the library consists of several small parts that can be used in many other places while a lot of C-libraries tend to be monolithic (like freetype2).
I have to admit that parsing ttf and the other formats is maybe more work then the what has been done so far.
Thanks to the developers of Blender who fixed a bug I described it is possible to load this file into Blender to generate a raytraced picture:

Example Rendering with Blender



Advertisements