mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 22:10:34 +00:00
🐛 Preserve swapped placement when its content main rotates
Prepare the content subtree in the swapped head's orientation before syncing it. A content main rotation must not replace the orientation of the position this head occupies in its enclosing component. The focused regression fails two assertions before the fix. Geometry, reset, swap and oracle suites pass 77 tests / 312 assertions. The original generated failure also passes after the fix. Benchmark vs Phase 1e: main 10/100/1000 0.51/0.57/0.57; levels 0.49; chain 0.49; library 0.54; many shapes 0.72; switch 0.64. No flags. AI-assisted-by: GPT-6
This commit is contained in:
parent
0859d7c1a1
commit
407e14682f
@ -261,17 +261,21 @@
|
||||
(recur shape-inst' next-data component')))))))
|
||||
|
||||
(defn- main-in-parent-orientation
|
||||
"Place a main in the orientation of an ordinary instance parent. Such a
|
||||
parent can survive detach, while the nested copy stays untouched."
|
||||
"Place a content main in the orientation of a swapped head, or compose
|
||||
the placement of an ordinary parent that survived detach."
|
||||
[main-container shape-main container shape-inst reset?]
|
||||
(let [parent (ctn/get-shape container (:parent-id shape-inst))
|
||||
main-parent (get-in main-container [:objects (:parent-id shape-main)])
|
||||
relative (gmt/multiply (or (:transform parent) (gmt/matrix))
|
||||
(or (:transform-inverse main-parent) (gmt/matrix)))]
|
||||
(if (or (nil? parent) (and (:shape-ref parent) (not reset?)) (gmt/unit? relative))
|
||||
swapped? (and (not reset?) (ctk/swapped? shape-inst))
|
||||
origin (if swapped? shape-main main-parent)
|
||||
target (if swapped? shape-inst parent)
|
||||
relative (gmt/multiply (or (:transform target) (gmt/matrix))
|
||||
(or (:transform-inverse origin) (gmt/matrix)))]
|
||||
(if (or (nil? target) (and (:shape-ref parent) (not reset?) (not swapped?))
|
||||
(gmt/unit? relative))
|
||||
main-container
|
||||
(let [transform (gmt/transform-in (gsh/shape->center shape-main) relative)
|
||||
angle (- (or (:rotation parent) 0) (or (:rotation main-parent) 0))
|
||||
angle (- (or (:rotation target) 0) (or (:rotation origin) 0))
|
||||
turn #(-> %
|
||||
(assoc-in [:modifiers :rotation] angle)
|
||||
(gsh/apply-transform transform)
|
||||
|
||||
@ -721,3 +721,16 @@
|
||||
head (tm/resolve-shape situation :plain-star)]
|
||||
(t/is (== 40 (:height head)))
|
||||
(t/is (not (ctk/touched-group? head :geometry-group)))))
|
||||
|
||||
(t/deftest swapped-copy-keeps-position-orientation-when-its-content-main-turns
|
||||
(let [initial (setup-sized)
|
||||
file (-> initial
|
||||
(tho/swap-component-in-shape :copy-star :heart)
|
||||
(transform-subtree :heart-main #(ctm/rotation-modifiers %1 %2 90))
|
||||
(propagate :heart))
|
||||
head (ths/get-shape file :copy-star)
|
||||
child (ths/get-shape-by-id file (first (:shapes head)))]
|
||||
(t/is (mth/close? 0 (:rotation head) 0.001))
|
||||
(t/is (mth/close? 0 (:rotation child) 0.001))
|
||||
(t/is (= #{:swap-group} (:touched head)))
|
||||
(t/is (nil? (:touched child)))))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user