Skip to content

Repair flip-x and flip-y - #91

Open
soegaard wants to merge 1 commit into
racket:masterfrom
soegaard:patch-4
Open

Repair flip-x and flip-y#91
soegaard wants to merge 1 commit into
racket:masterfrom
soegaard:patch-4

Conversation

@soegaard

Copy link
Copy Markdown
Member

Close: #84

@benknoble

Copy link
Copy Markdown
Contributor

Nice! FWIW, I probably would have force-pushed the branch associated with the other PR, but this will work. Thanks!

@mflatt

mflatt commented Oct 21, 2025

Copy link
Copy Markdown
Member

Should ascent and descent get swapped by flip-y? Or should they cross (so that the descent line ends up above the ascent line)?

@soegaard

Copy link
Copy Markdown
Member Author

The intention was for them to cross.
But maybe it is better to keep the existing behavior?
It all depends on what we expect to work.

If we want to flip a single word in a sentence of normal text,
then we should keep ascent and descent untouched.

If we want to append several pieces of flipped text, then I think the
baseline should move.

The test program below show what happens with:

Options for ascent, descent:
  original:  a d
  swapped:   d a
  other     -d d+h  (sine a+d = h)

Only the original passes the (flip-y (flip-y p)) test.

image
#lang racket
(require pict)

(define (flip-x p)
  (define w      (pict-width   p))
  (define h      (pict-height  p))
  (define a      (pict-ascent  p))
  (define d      (pict-descent p))
  (define w/2    (/ w 2.))
  (define drawer (make-pict-drawer p))
  (define new    (dc (λ (dc x y)
                       ;; ( x,  y) is the top-left corner
                       ;; (cx, cy) is the center of the upper side
                       (define cx (+ x w/2))
                       (define cy y)
                       (define old-t (send dc get-transformation))
                       ; Move center of upper side to (0,0)
                       (send dc translate cx cy)
                       (send dc transform #(-1 0 0 1 0 0))
                       (drawer dc (- w/2) 0)
                       (send dc set-transformation old-t))
                     w h
                     a d))
  (make-pict (pict-draw new)
             w h a d
             (list (make-child p 1 0 0 1 0 0))
             #f
             (pict-last p)))

(define (flip-y p #:option [option 'original])
  (define w      (pict-width   p))
  (define h      (pict-height  p))
  (define a      (pict-ascent  p))
  (define d      (pict-descent p))
  (define h/2    (/ h 2))
  (define drawer (make-pict-drawer p))
  (define new    (dc (λ (dc x y)
                       ;; ( x,  y) is the top-left corner
                       ;; (cx, cy) is the center of the left side
                       (define cx x)
                       (define cy (+ y h/2))
                       (define old-t (send dc get-transformation))
                       ; Move center of left side to (0,0)
                       (send dc translate cx cy)
                       (send dc transform #(1 0 0 -1 0 0))
                       (drawer dc 0 (- h/2))
                       (send dc set-transformation old-t))
                     w h
                     ; Available options for ascent, descent:
                     ;  original:  a d
                     ;  swapped:   d a
                     ;  other     -d d+h  (sine a+d = h)
                     (case option [(original) a] [(swapped) d] [(other) (- d)])
                     (case option [(original) d] [(swapped) a] [(other) (+ d h)])))
  (make-pict (pict-draw    new)
             (pict-width   new)
             (pict-height  new)
             (pict-ascent  new)
             (pict-descent new)
             (list (make-child p 1 0 0 1 0 0))
             #f
             (pict-last p)))

(define options '(original swapped other))

"Appending flipped text with flipped text"
(apply vl-append
       (for/list ([opt options])
         (scale (hbl-append (flip-y (text "Hello") #:option opt)
                            (flip-y (text "World") #:option opt)) 4)))

"Appending flipped text with normal text"
(apply vl-append
       (for/list ([opt options])
         (scale (hbl-append (flip-y (text "Hello") #:option opt)
                                    (text "World")) 4)))

"Testing that (flip-y (flip-y p)) = p"
(apply vl-append
       (for/list ([opt options])
         (ht-append
          (frame (flip-y (hbl-append (flip-y (text "Hello") #:option opt)
                                     (blank 10)
                                     (flip-y (text "world")))))
          (blank 10)
          (frame         (hbl-append         (text "Hello")
                                             (blank 10)
                                             (text "world"))))))

@rfindler

Copy link
Copy Markdown
Member

If I'm following correctly, original and swapped both seem like legit things that folks might want (and I'd lean towards an optional argument with a default that matches the previous behavior, which is what it looks like you've got in the code). What is the point of the third option?

@soegaard

Copy link
Copy Markdown
Member Author

The test code was just to make experimentation with various options for ascent and descent easier - so the third option is for your experiments ;-)

Matthew:
Or should they cross (so that the descent line ends up above the ascent line)?

I am unsure whether other matches this or not.

If I'm following correctly, original and swapped both seem like legit things that folks might want (and I'd lean towards an optional argument with a default that matches the previous behavior, which is what it looks like you've got in the code).

Then a better name than #:option is needed. Maybe #:mode ?

@rfindler

Copy link
Copy Markdown
Member

#:swap-baseline? or #:swap-lines? maybe?

@benknoble

benknoble commented Oct 22, 2025

Copy link
Copy Markdown
Contributor

The test program below show what happens with:


Options for ascent, descent:

  original:  a d

  swapped:   d a

  other     -d d+h  (sine a+d = h)

Only the original passes the (flip-y (flip-y p)) test.

This is a small nit, but the test program actually does something like compare p = (combine a b c) with q = (flip-y (combine (flip-y a) b (flip-y c))). It's not obvious to me that p and q should be the same there; maybe they should be, but it's a bit different to me from flipping twice w/o intervention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Something is rotten in flip-x/flip-y

4 participants