Kerning Problem with Latin Modern Roman

I have a kerning problem with the font "Latin Modern Roman" (maybe also with others). I wrote a program which draws "Hello, World!" (source at the bottom). Next I made a screenshot and imported the screenshot into Inkscape.I created the same text with Inkscape and aligned the "W" so that both lines should have the same size. Then I made another screenshot.

The result is: Racket creates a bigger gap between the "W" and the "o" than Inkscape. Inkscape looks nice, Racket does not look nice. You can see it in the attached screenshot.

My question: how can I fix this?

#lang racket/gui

(define (frame-label area)
  (let ((p (send area get-parent)))
    (if p
        (frame-label p)
        (send area get-label))))

(define shell%
  (class canvas%
    (init parent)
    (super-new (parent parent))

    (let ((dc (send this get-dc)))
      (send dc set-font (make-font #:size 80 #:face "Latin Modern Roman")) ;; Fira Code
      (send dc set-pen "black" 0 'solid)
      (send dc set-smoothing 'unsmoothed)
      (send dc set-brush "white" 'transparent))

    (define/override (on-event event)
      (printf "event: x=~s y=~s mouse=~s\n"
              (send event get-x)
              (send event get-y)
              (send event get-event-type)))

    (define/override (on-char event)
      (printf "event: key=~s\n"
              (send event get-key-code)))

    (define/public (draw-text-center text bounding-box baseline)
      (let ((dc (send this get-dc)))
        (let*-values ([(dc-width dc-height) (send dc get-size)]
                      [(text-width text-height baseline-height extra-height)
                       (send dc get-text-extent text)])
          (let* ((offset-x (/ (- dc-width text-width) 2))
                 (offset-y (/ (- dc-height text-height) 2))
                 (baseline-y (- (+ offset-y text-height) baseline-height))
                 (margin-x (- (+ offset-x text-width) 1)))
            (send dc draw-text text offset-x offset-y)
            (when bounding-box
              (send dc draw-rectangle offset-x offset-y text-width text-height))
            (when baseline
              (send dc draw-line offset-x baseline-y margin-x baseline-y))))))

    (define/override (on-paint)
      (send this draw-text-center (frame-label this) #t #t))

    (define/public (size)
      (let ((dc (send this get-dc)))
        (let*-values ([(dc-width dc-height) (send dc get-size)]
                      [(text-width text-height baseline-height extra-height)
                       (send dc get-text-extent "█")])
          (values (/ dc-width text-width)
                  (/ dc-height text-height)))))
    ))

(define frame (new frame%
                   [label "Hello, World!"]
                   [width 700]
                   [height 200]))

(define shell (new shell% [parent frame]))

(send frame show #t)

Does it help to pass a true value for the combine argument to draw-text? Maybe like this:

(send dc draw-text text offset-x offset-y 'grapheme)

No does not work.

It seems to me that "draw" does not know much about kerning. I can not find anything in the class font%. The only place, where I can find kerning is sfont.

For reference (from the docs for draw-text):

I see. It is necessary to enable kerning. It is not the default to use the kerning table of the font.

#lang racket/gui

(define (integer-ceiling x)
  (inexact->exact (ceiling x)))

(define frame (new frame% [label ""]))
(define font (make-font #:size 80 #:face "Latin Modern Roman"))
(define txt (apply string-append (make-list 5 "AV")))

(define (draw c dc)
  (send dc set-pen "black" 0 'solid)
  (send dc set-smoothing 'unsmoothed)
  (send dc set-brush "white" 'transparent)
  (send dc set-font font)
  (let*-values (((w1 h1 d1 a1) (send dc get-text-extent txt font))
                ((w2 h2 d2 a2) (send dc get-text-extent txt font #t))
                ((x1 y1) (values 10 10))
                ((x2 y2) (values x1 (+ y1 h1 y1))))
    (send dc draw-rectangle x1 y1 w1 h1)
    (send dc draw-rectangle x2 y2 w2 h2)
    (send dc draw-text txt x1 y1)
    (send dc draw-text txt x2 y2 #t)
    (send frame resize
          (integer-ceiling (+ (* x1 2) (max w1 w2)))
          (integer-ceiling (+ y2 h2 y1)))))

(define canvas (new canvas% [parent frame] [paint-callback draw]))
(send frame show #t)
1 Like