From 8c25fb00ac4775672679dcc0da20752278234b51 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 29 Jan 2026 07:34:20 +0100 Subject: [PATCH] :bug: Fix auto width/height texts on variant swithching --- common/src/app/common/logic/libraries.cljc | 8 ++- .../app/main/data/workspace/libraries.cljs | 12 ++++ .../src/app/main/data/workspace/texts.cljs | 55 ++------------ .../data/workspace/tokens/application.cljs | 8 +-- .../app/main/data/workspace/wasm_text.cljs | 72 +++++++++++++++++++ .../workspace/sidebar/options/menus/text.cljs | 3 +- 6 files changed, 102 insertions(+), 56 deletions(-) create mode 100644 frontend/src/app/main/data/workspace/wasm_text.cljs diff --git a/common/src/app/common/logic/libraries.cljc b/common/src/app/common/logic/libraries.cljc index 0d291a94f4..d42535e3d2 100644 --- a/common/src/app/common/logic/libraries.cljc +++ b/common/src/app/common/logic/libraries.cljc @@ -2017,7 +2017,9 @@ (let [;; We need to sync only the position relative to the origin of the component. ;; (see update-attrs for a full explanation) previous-shape (reposition-shape previous-shape prev-root current-root) - touched (get previous-shape :touched #{})] + touched (get previous-shape :touched #{}) + text-auto? (and (cfh/text-shape? current-shape) + (contains? #{:auto-height :auto-width} (:grow-type current-shape)))] (loop [attrs updatable-attrs roperations [{:type :set-touched :touched (:touched previous-shape)}] @@ -2026,6 +2028,10 @@ (let [attr-group (get ctk/sync-attrs attr) skip-operations? (or + ;; For auto text, avoid copying geometry-driven attrs on switch. + (and text-auto? + (contains? #{:points :selrect :width :height :position-data} attr)) + ;; If the attribute is not valid for the destiny, don't copy it (not (cts/is-allowed-switch-keep-attr? attr (:type current-shape))) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 2fb6a96650..803edbfa51 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -46,7 +46,9 @@ [app.main.data.workspace.thumbnails :as dwt] [app.main.data.workspace.transforms :as dwtr] [app.main.data.workspace.undo :as dwu] + [app.main.data.workspace.wasm-text :as dwwt] [app.main.data.workspace.zoom :as dwz] + [app.main.features :as features] [app.main.features.pointer-map :as fpmap] [app.main.refs :as refs] [app.main.repo :as rp] @@ -1012,6 +1014,13 @@ updated-objects (pcb/get-objects changes) new-children-ids (cfh/get-children-ids-with-self updated-objects (:id new-shape)) + new-text-ids (->> new-children-ids + (keep (fn [id] + (when-let [child (get updated-objects id)] + (when (and (cfh/text-shape? child) + (not= :fixed (:grow-type child))) + id)))) + (vec)) [changes parents-of-swapped] (if keep-touched? @@ -1021,6 +1030,9 @@ (rx/of (dwu/start-undo-transaction undo-id) (dch/commit-changes changes) + (when (and (features/active-feature? state "render-wasm/v1") + (seq new-text-ids)) + (dwwt/resize-wasm-text-all new-text-ids)) (ptk/data-event :layout/update {:ids update-layout-ids :undo-group undo-group}) (dwu/commit-undo-transaction undo-id) (dws/select-shape (:id new-shape) false)))))) diff --git a/frontend/src/app/main/data/workspace/texts.cljs b/frontend/src/app/main/data/workspace/texts.cljs index f2fdf75aa4..54fcf70abc 100644 --- a/frontend/src/app/main/data/workspace/texts.cljs +++ b/frontend/src/app/main/data/workspace/texts.cljs @@ -11,7 +11,6 @@ [app.common.data :as d] [app.common.data.macros :as dm] [app.common.files.helpers :as cfh] - [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] [app.common.geom.shapes :as gsh] [app.common.math :as mth] @@ -29,10 +28,10 @@ [app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.transforms :as dwt] [app.main.data.workspace.undo :as dwu] + [app.main.data.workspace.wasm-text :as dwwt] [app.main.features :as features] [app.main.fonts :as fonts] [app.main.router :as rt] - [app.render-wasm.api :as wasm.api] [app.util.text-editor :as ted] [app.util.text.content.styles :as styles] [app.util.timers :as ts] @@ -52,50 +51,6 @@ (declare v2-update-text-shape-content) (declare v2-update-text-editor-styles) -(defn resize-wasm-text-modifiers - ([shape] - (resize-wasm-text-modifiers shape (:content shape))) - - ([{:keys [id points selrect grow-type] :as shape} content] - (wasm.api/use-shape id) - (wasm.api/set-shape-text-content id content) - (wasm.api/set-shape-text-images id content) - - (let [dimension (wasm.api/get-text-dimensions) - width-scale (if (#{:fixed :auto-height} grow-type) - 1.0 - (/ (:width dimension) (:width selrect))) - height-scale (if (= :fixed grow-type) - 1.0 - (/ (:height dimension) (:height selrect))) - resize-v (gpt/point width-scale height-scale) - origin (first points)] - - {id - {:modifiers - (ctm/resize-modifiers - resize-v - origin - (:transform shape (gmt/matrix)) - (:transform-inverse shape (gmt/matrix)))}}))) - -(defn resize-wasm-text - [id] - (ptk/reify ::resize-wasm-text - ptk/WatchEvent - (watch [_ state _] - (let [objects (dsh/lookup-page-objects state) - shape (get objects id)] - (rx/of (dwm/apply-wasm-modifiers (resize-wasm-text-modifiers shape))))))) - -(defn resize-wasm-text-all - [ids] - (ptk/reify ::resize-wasm-text-all - ptk/WatchEvent - (watch [_ _ _] - (->> (rx/from ids) - (rx/map resize-wasm-text))))) - ;; -- Content helpers (defn- v2-content-has-text? @@ -178,7 +133,7 @@ {:undo-group (when new-shape? id)}) (dwm/apply-wasm-modifiers - (resize-wasm-text-modifiers shape content) + (dwwt/resize-wasm-text-modifiers shape content) {:undo-group (when new-shape? id)}))))) (let [content (d/merge (ted/export-content content) @@ -823,7 +778,7 @@ (when (features/active-feature? state "render-wasm/v1") ;; This delay is to give time for the font to be correctly rendered ;; in wasm. - (cond->> (rx/of (resize-wasm-text id)) + (cond->> (rx/of (dwwt/resize-wasm-text id)) (contains? attrs :font-id) (rx/delay 200))))))) @@ -973,11 +928,11 @@ (if (and (not= :fixed (:grow-type shape)) finalize?) (dwm/apply-wasm-modifiers - (resize-wasm-text-modifiers shape content) + (dwwt/resize-wasm-text-modifiers shape content) {:undo-group (when new-shape? id)}) (dwm/set-wasm-modifiers - (resize-wasm-text-modifiers shape content) + (dwwt/resize-wasm-text-modifiers shape content) {:undo-group (when new-shape? id)}))) (when finalize? diff --git a/frontend/src/app/main/data/workspace/tokens/application.cljs b/frontend/src/app/main/data/workspace/tokens/application.cljs index 9110e81da0..4966942876 100644 --- a/frontend/src/app/main/data/workspace/tokens/application.cljs +++ b/frontend/src/app/main/data/workspace/tokens/application.cljs @@ -27,9 +27,9 @@ [app.main.data.workspace.colors :as wdc] [app.main.data.workspace.shape-layout :as dwsl] [app.main.data.workspace.shapes :as dwsh] - [app.main.data.workspace.texts :as dwt] [app.main.data.workspace.transforms :as dwtr] [app.main.data.workspace.undo :as dwu] + [app.main.data.workspace.wasm-text :as dwwt] [app.main.features :as features] [app.main.fonts :as fonts] [app.main.store :as st] @@ -315,7 +315,7 @@ (and affects-layout? (features/active-feature? state "render-wasm/v1")) (rx/merge - (rx/of (dwt/resize-wasm-text-all shape-ids)))))))) + (rx/of (dwwt/resize-wasm-text-all shape-ids)))))))) (defn update-line-height ([value shape-ids attributes] (update-line-height value shape-ids attributes nil)) @@ -374,7 +374,7 @@ :page-id page-id})) (features/active-feature? state "render-wasm/v1") (rx/merge - (rx/of (dwt/resize-wasm-text-all shape-ids)))))))) + (rx/of (dwwt/resize-wasm-text-all shape-ids)))))))) (defn- create-font-family-text-attrs [value] @@ -451,7 +451,7 @@ :page-id page-id})) (features/active-feature? state "render-wasm/v1") (rx/merge - (rx/of (dwt/resize-wasm-text-all shape-ids)))))))) + (rx/of (dwwt/resize-wasm-text-all shape-ids)))))))) (defn update-font-weight ([value shape-ids attributes] (update-font-weight value shape-ids attributes nil)) diff --git a/frontend/src/app/main/data/workspace/wasm_text.cljs b/frontend/src/app/main/data/workspace/wasm_text.cljs new file mode 100644 index 0000000000..2174ba7161 --- /dev/null +++ b/frontend/src/app/main/data/workspace/wasm_text.cljs @@ -0,0 +1,72 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.data.workspace.wasm-text + "Helpers/events to resize wasm text shapes without depending on workspace.texts. + + This exists to avoid circular deps: + workspace.texts -> workspace.libraries -> workspace.texts" + (:require + [app.common.files.helpers :as cfh] + [app.common.geom.matrix :as gmt] + [app.common.geom.point :as gpt] + [app.common.types.modifiers :as ctm] + [app.main.data.helpers :as dsh] + [app.main.data.workspace.modifiers :as dwm] + [app.render-wasm.api :as wasm.api] + [beicon.v2.core :as rx] + [potok.v2.core :as ptk])) + +(defn resize-wasm-text-modifiers + ([shape] + (resize-wasm-text-modifiers shape (:content shape))) + + ([{:keys [id points selrect grow-type] :as shape} content] + (wasm.api/use-shape id) + (wasm.api/set-shape-text-content id content) + (wasm.api/set-shape-text-images id content) + + (let [dimension (wasm.api/get-text-dimensions) + width-scale (if (#{:fixed :auto-height} grow-type) + 1.0 + (/ (:width dimension) (:width selrect))) + height-scale (if (= :fixed grow-type) + 1.0 + (/ (:height dimension) (:height selrect))) + resize-v (gpt/point width-scale height-scale) + origin (first points)] + + {id + {:modifiers + (ctm/resize-modifiers + resize-v + origin + (:transform shape (gmt/matrix)) + (:transform-inverse shape (gmt/matrix)))}}))) + +(defn resize-wasm-text + "Resize a single text shape (auto-width/auto-height) by id. + No-op if the id is not a text shape or is :fixed." + [id] + (ptk/reify ::resize-wasm-text + ptk/WatchEvent + (watch [_ state _] + (let [objects (dsh/lookup-page-objects state) + shape (get objects id)] + (if (and (some? shape) + (cfh/text-shape? shape) + (not= :fixed (:grow-type shape))) + (rx/of (dwm/apply-wasm-modifiers (resize-wasm-text-modifiers shape))) + (rx/empty)))))) + +(defn resize-wasm-text-all + "Resize all text shapes (auto-width/auto-height) from a collection of ids." + [ids] + (ptk/reify ::resize-wasm-text-all + ptk/WatchEvent + (watch [_ _ _] + (->> (rx/from ids) + (rx/map resize-wasm-text))))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs index c2f9226250..04e05ae53f 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/text.cljs @@ -15,6 +15,7 @@ [app.main.data.workspace.shortcuts :as sc] [app.main.data.workspace.texts :as dwt] [app.main.data.workspace.undo :as dwu] + [app.main.data.workspace.wasm-text :as dwwt] [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] @@ -138,7 +139,7 @@ (dwsh/update-shapes ids #(assoc % :grow-type grow-type))) (when (features/active-feature? @st/state "render-wasm/v1") - (st/emit! (dwt/resize-wasm-text-all ids))) + (st/emit! (dwwt/resize-wasm-text-all ids))) ;; We asynchronously commit so every sychronous event is resolved first and inside the transaction (ts/schedule #(st/emit! (dwu/commit-undo-transaction uid)))) (when (some? on-blur) (on-blur))))]