racket / plot

Other
40 stars 37 forks source link

Some incomplete letters in the y-label (with 'swiss font) in plot package #109

Open encomer opened 2 years ago

encomer commented 2 years ago

Running Racket 8.4 [cs], the following example program:

#lang racket
(require plot)
(parameterize
    ([plot-font-size 12]
     [plot-font-family 'swiss])
  (plot (vector-field
    (λ (x y) (vector (+ x y) (- x y)))
    -2 2 -2 2)
   #:x-label "abcdefghijklmnñopqrstuvwxyz"
   #:y-label "abcdefghijklmnñopqrstuvwxyz"))

Results in rendering the y-label, with some letters (h, n, ñ, u) incomplete. Notice that there is no problem in the x-label letters. In other font sizes this problem may not happen. Something similar happens with the 'decorative font.

Thank you in advance for your support, and congratulations for the great work. Best regards.

sorawee commented 2 years ago

This probably should be moved to racket/plot.

soegaard commented 2 years ago

This is how it looks on my computer (macOS).

image

I think it looks fine?

alex-hhh commented 2 years ago

It also looks correct on Windows, with Racket 8.4 cs.

@encomer , can you please attach a screen shot of what it looks on your computer? Also could you please include the Racket version and OS you are using.

encomer commented 2 years ago

Yes @alex-hhh , the screen shot in my computer is: image My OS is Windows 10. The "right side cutting" of the mentioned letters (h, n, ñ, u) in the y-label, seems not to come from a superposition of the next letter, because if I change "z" for "n" the result looks like an "r". This "effect" occurs in my case, only with font-size 12, and with font-family 'swiss or 'decorative.

Note: in my scribble document, I temporaly changed font-size to 13, to generate correctly the HTML as well as the PDF rendering of the y-label. I understand that this is a minor issue, but interesting in itself.

Thank you again for your support.

alex-hhh commented 2 years ago

Thanks for the screenshot. I can reproduce the problem when rendering the plot on a non-HighDPI display (i.e. a Full HD one with a backing scale of 1.0). The problem does not happen when rendering the plot on HighDPI displays with a backing scale greater than 1.0.

I can also see that increasing the font size to 13 makes this a workaround.

I suspect the problem is somewhere in the drawing libraries, with drawing text at a 90 degree angle, but I will need to investigate this a bit more.

alex-hhh commented 2 years ago

Unfortunately I could not determine what causes this issue, but I will write down my notes.

The program below will reproduce the issue regardless of the monitor DPI. @soegaard , could you test this on MacOS, to see if the problem is happening there:

#lang racket/gui
(require plot
         plot/private/common/draw
         racket/draw)

(define str "abcdefghijklmnñopqrstuvwxyz1")

(parameterize
    ([plot-font-size 12]
     [plot-font-family 'swiss]
     [plot-y-far-label str])
  (define bm (make-object bitmap% (plot-width) (plot-height) #f #t 1.0))
  (define dc (new bitmap-dc% [bitmap bm]))
  (plot/dc
   (vector-field
    (λ (x y) (vector (+ x y) (- x y)))
    -2 2 -2 2)
   dc 0 0 (plot-width) (plot-height)
   #:x-label str
   #:y-label str
   #:title str)
  bm)

The snippet below can be used to obtain all the draw commands issued while creating the plot:

(parameterize
    ([plot-font-size 12]
     [plot-font-family 'swiss]
     [plot-y-far-label str])
  (define dc (new record-dc% [width (plot-width)] [height (plot-height)]))
  (plot/dc
   (vector-field
    (λ (x y) (vector (+ x y) (- x y)))
    -2 2 -2 2)
   dc 0 0 (plot-width) (plot-height)
   #:x-label str
   #:y-label str
   #:title str)
  (send dc get-recorded-datum))

Unfortunately, trying to isolate just drawing the vertical text did not reproduce the problem on my machine. The code below attempts to reproduce the drawing of the Y axis label:

(let* ([bm (make-object bitmap% (plot-width) (plot-height) #f #t 1.0)]
       [dc (new bitmap-dc% [bitmap bm])]
       [font (send the-font-list find-or-create-font 12 'swiss 'normal 'normal)]
       [x 0]
       [y (/ (plot-height) 2)])
  (send dc set-text-mode 'transparent)
  (send dc set-background "white")
  (send dc set-text-foreground "black")
  (send dc set-alpha 1)

  (when #t
    ;(define alpha (send dc get-alpha))
    (define fg (send dc get-text-foreground))

    ;(send dc set-alpha (alpha-expt alpha 1/2))
    (send dc set-text-foreground (send dc get-background))
    (for* ([dx  (list -1 0 1)]
           [dy  (list -1 0 1)]
           #:when (not (and (zero? dx) (zero? dy))))
      (draw-text/anchor dc str (+ x dx) (+ y dy) 'top (/ pi 2)))
    ;(send dc set-alpha alpha)
    (send dc set-text-foreground fg))

  (draw-text/anchor dc str x y 'top (/ pi 2))

  bm)
soegaard commented 2 years ago

DrRacket 8.4 macOS.

image
alex-hhh commented 2 years ago

Actually, in my previous example, I forgot to set the font before drawing and this is why I could not reproduce the problem with a separate draw program...

This looks like is a problem with racket/draw (or cairo libraries), since I can reproduce it using the program below. It looks like it is happening for 'swiss font family when drawing vertically at font sizes 11 and 12, but not 13 and 14.

Also, if I use a higher backing scale for the bitmap (such as 1.5 or 2.0), the problem disappears as well.

#lang racket
(require racket/draw)

(define backing-scale 1.0)

(let* ([bm (make-object bitmap% 400 400 #f #t backing-scale)]
       [dc (new bitmap-dc% [bitmap bm])])

  (send dc set-smoothing 'smoothed)

  (send dc set-font (send the-font-list find-or-create-font 12 'swiss 'normal 'normal))
  (send dc draw-text "(11) abcdefghijklmnñopqrstuvwxyz1" 10 350 #t 0 (/ pi 2))

  (send dc set-font (send the-font-list find-or-create-font 12 'swiss 'normal 'normal))
  (send dc draw-text "(12) abcdefghijklmnñopqrstuvwxyz1" 40 350 #t 0 (/ pi 2))

  (send dc set-font (send the-font-list find-or-create-font 13 'swiss 'normal 'normal))
  (send dc draw-text "(13) abcdefghijklmnñopqrstuvwxyz1" 60 350 #t 0 (/ pi 2))

  (send dc set-font (send the-font-list find-or-create-font 14 'swiss 'normal 'normal))
  (send dc draw-text "(14) abcdefghijklmnñopqrstuvwxyz1" 80 350 #t 0 (/ pi 2))

  bm)
image
encomer commented 2 years ago

Thank you @alex-hhh for your code. Actually it looks like with font-size 13 we have a little problem with the "s" letter. I ran a little experiment with the help of your code:

#lang racket
(require racket/draw)
(define backing-scale 1.0)
(let* ([bm (make-object bitmap%
             800 800 #f #t backing-scale)]
       [dc (new bitmap-dc% [bitmap bm])])  
  (send dc set-smoothing 'smoothed)
  (send dc set-font
        (send the-font-list
              find-or-create-font 12
              'swiss 'normal 'normal))
  (send dc draw-text
        "(12) abcdefghijklmnñopqrstuvwxyz1"
        40 350
        #t 0 (* pi (- 0.5 1e-6)))  
  bm)

And the result was: image That is, the problem occurs only when we apply a rotation of exactly 90 degrees, or exactly 270 degrees. So, may be the code that renders the image is using a little different transformation for these two special cases.

Thank you very much for your support.