anchor.diff:      open System.Threading
       open Aardvark.Base.Rendering
   
  -    module GDI =
  +    module GDI32 =
           open System.Runtime.InteropServices
           open Microsoft.FSharp.NativeInterop
           open System.Collections.Generic
   
  -        type KerningPair =
  -            struct
  -                val mutable public first : uint16
  -                val mutable public second : uint16
  -                val mutable public amount : int
  -            end
  -
  -        [<DllImport("gdi32.dll")>]
  -        extern int GetKerningPairs(nativeint hdc, int count, KerningPair* pairs)
  -
  -        [<DllImport("gdi32.dll")>]
  -        extern nativeint SelectObject(nativeint hdc,nativeint hFont)
  -
  -
  -        let pairs (f : Font) =
  -            use f = new System.Drawing.Font(f.FontFamily, 2000.0f, f.Style, GraphicsUnit.Pixel, f.GdiCharSet, f.GdiVerticalFont)
  -            use g = Graphics.FromHwnd(0n)
  -            g.PageUnit <- GraphicsUnit.Point
  -
  +
  +        [<AutoOpen>]
  +        module private Wrappers = 
  +            [<StructLayout(LayoutKind.Sequential)>]
  +            type KerningPair =
  +                struct
  +                    val mutable public first : uint16
  +                    val mutable public second : uint16
  +                    val mutable public amount : int
  +                end
  +
  +            [<StructLayout(LayoutKind.Sequential)>]
  +            type ABC =
  +                struct
  +                    val mutable public A : float32
  +                    val mutable public B : float32
  +                    val mutable public C : float32
  +                end
  +
  +            [<DllImport("gdi32.dll")>]
  +            extern int GetKerningPairs(nativeint hdc, int count, KerningPair* pairs)
  +
  +            [<DllImport("gdi32.dll")>]
  +            extern nativeint SelectObject(nativeint hdc,nativeint hFont)
  +
  +            [<DllImport("gdi32.dll")>]
  +            extern bool GetCharABCWidthsFloat(nativeint hdc, uint32 first, uint32 last, ABC* pxBuffer)
  +
  +            [<DllImport("gdi32.dll")>]
  +            extern bool GetCharWidthFloat(nativeint hdc, uint32 first, uint32 last, float32* pxBuffer)
  +
  +
  +        let getKerningPairs (g : Graphics) (f : Font) =
               let hdc = g.GetHdc()
               let hFont = f.ToHfont()
               let old = SelectObject(hdc, hFont)
  -
  -            let cnt = GetKerningPairs(hdc, 0, NativePtr.zero)
  -            let ptr = NativePtr.stackalloc cnt
  -            GetKerningPairs(hdc, cnt, ptr) |> ignore
  -
  -            let res = Dictionary<char * char, float>()
  -            for i in 0..cnt-1 do
  -                let pair = NativePtr.get ptr i
  -                let c0 = pair.first |> char
  -                let c1 = pair.second |> char
  -                res.[(c0,c1)] <- float pair.amount / 2000.0
  -
  -            res
  +            try
  +                let cnt = GetKerningPairs(hdc, 0, NativePtr.zero)
  +                let ptr = NativePtr.stackalloc cnt
  +                GetKerningPairs(hdc, cnt, ptr) |> ignore
  +
  +                let res = Dictionary<char * char, float>()
  +                for i in 0..cnt-1 do
  +                    let pair = NativePtr.get ptr i
  +                    let c0 = pair.first |> char
  +                    let c1 = pair.second |> char
  +                    res.[(c0,c1)] <- float pair.amount / float f.Size
  +
  +                res
  +            finally
  +                SelectObject(hdc, old) |> ignore
  +                g.ReleaseHdc(hdc)
  +
  +        let getCharWidths (g : Graphics) (f : Font) (c : char) =
  +            let hdc = g.GetHdc()
  +
  +            let old = SelectObject(hdc, f.ToHfont())
  +            try
  +                let mutable size = ABC()
  +                if GetCharABCWidthsFloat(hdc, uint32 c, uint32 c, &&size) then
  +                    V3d(size.A, size.B, size.C) / float f.Size
  +                else
  +                    let mutable size = 0.0f
  +                    if GetCharWidthFloat(hdc, uint32 c, uint32 c, &&size) then
  +                        V3d(0.0, float size, 0.0) / float f.Size
  +                    else
  +                        Log.warn "no width for: '%c'" c
  +                        V3d.Zero
  +            finally
  +                SelectObject(hdc, old) |> ignore
  +                g.ReleaseHdc(hdc)
  +
  +    module FontInfo =
  +        let getKerningPairs (g : Graphics) (f : Font) =
  +            match Environment.OSVersion with
  +                | Windows -> GDI32.getKerningPairs g f
  +                | Linux -> failwithf "[Font] implement kerning for Linux"
  +                | Mac -> failwithf "[Font] implement kerning for Mac OS"
  +
  +        let getCharWidths (g : Graphics) (f : Font) (c : char) =
  +            match Environment.OSVersion with
  +                | Windows -> GDI32.getCharWidths g f c
  +                | Linux -> failwithf "[Font] implement character sizes for Linux"
  +                | Mac -> failwithf "[Font] implement character sizes for Mac OS"
  +
   
       type FontCache(r : IRuntime, f : Font) =
           let pool = Aardvark.Base.Rendering.GeometryPool.createAsync r
  
positive.code:         )
  
  
          win.Keyboard.Press.Values.Add (fun c ->
              transact (fun () -> text.Value <- sprintf "%s%c" text.Value c)
          )
  
negative.code:             f.Dispose()
              kerning.Clear()
              glyphs.Clear()
              largeScaleFont.Dispose()
              graphics.Dispose()
  
          member x.Layout (str : string, spacing : float) =
              let mutable cx = 0.0
              let mutable cy = 0.0
  
              let arr = List<V2d * char>()
  
              for i in 0..str.Length-1 do
                  let c = str.[i]
  
                  match c with
                      | '\r' -> cx <- 0.0
                      | '\n' -> cy <- cy + 1.2
                      | _ ->
                          let sizes = getGlyphSizes c
                          let kerning = 
                              if i > 0 then x.GetKerning(str.[i-1], c)
                              else 0.0
  
  
                          let before = kerning
                          let width = sizes.X + sizes.Y + sizes.Z
  
                          if not (c.IsWhiteSpace()) then
                              arr.Add(V2d(cx + before * spacing, cy), c)
  
                          cx <- cx + width * spacing
  
              arr.ToArray()
  
          new(family : string, style : FontStyle) =
              let f = new System.Drawing.Font(family, 1.0f, style, GraphicsUnit.Point)
  