mirror of
https://github.com/penpot/penpot.git
synced 2025-06-05 08:31:39 +02:00
✨ Set selrect for new render modifiers
This commit is contained in:
parent
6831acb71d
commit
fef08dfa18
13 changed files with 200 additions and 72 deletions
|
@ -195,6 +195,7 @@
|
||||||
|
|
||||||
;; Rect
|
;; Rect
|
||||||
(dm/export grc/rect->points)
|
(dm/export grc/rect->points)
|
||||||
|
(dm/export grc/center->rect)
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(dm/export gsff/fit-frame-modifiers)
|
(dm/export gsff/fit-frame-modifiers)
|
||||||
|
|
|
@ -504,6 +504,13 @@
|
||||||
(filter (fn [[_ {:keys [type]}]]
|
(filter (fn [[_ {:keys [type]}]]
|
||||||
(= type :change-property)))))
|
(= type :change-property)))))
|
||||||
|
|
||||||
|
(defn set-temporary-selrect
|
||||||
|
[selrect]
|
||||||
|
(ptk/reify ::set-temporary-selrect
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(assoc state :workspace-selrect selrect))))
|
||||||
|
|
||||||
#_:clj-kondo/ignore
|
#_:clj-kondo/ignore
|
||||||
(defn set-wasm-modifiers
|
(defn set-wasm-modifiers
|
||||||
[modif-tree & {:keys [ignore-constraints ignore-snap-pixel]
|
[modif-tree & {:keys [ignore-constraints ignore-snap-pixel]
|
||||||
|
@ -519,8 +526,8 @@
|
||||||
(assoc :prev-wasm-props (:wasm-props state))
|
(assoc :prev-wasm-props (:wasm-props state))
|
||||||
(assoc :wasm-props property-changes))))
|
(assoc :wasm-props property-changes))))
|
||||||
|
|
||||||
ptk/EffectEvent
|
ptk/WatchEvent
|
||||||
(effect [_ state _]
|
(watch [_ state _]
|
||||||
(wasm.api/clean-modifiers)
|
(wasm.api/clean-modifiers)
|
||||||
|
|
||||||
(let [prev-wasm-props (:prev-wasm-props state)
|
(let [prev-wasm-props (:prev-wasm-props state)
|
||||||
|
@ -531,8 +538,9 @@
|
||||||
|
|
||||||
(let [structure-entries (parse-structure-modifiers modif-tree)]
|
(let [structure-entries (parse-structure-modifiers modif-tree)]
|
||||||
(wasm.api/set-structure-modifiers structure-entries)
|
(wasm.api/set-structure-modifiers structure-entries)
|
||||||
(let [geometry-entries (parse-geometry-modifiers modif-tree)]
|
(let [geometry-entries (parse-geometry-modifiers modif-tree)
|
||||||
(wasm.api/propagate-apply geometry-entries)))))))
|
selrect (wasm.api/propagate-apply geometry-entries)]
|
||||||
|
(rx/of (set-temporary-selrect selrect))))))))
|
||||||
|
|
||||||
#_:clj-kondo/ignore
|
#_:clj-kondo/ignore
|
||||||
(defn apply-wasm-modifiers
|
(defn apply-wasm-modifiers
|
||||||
|
@ -567,14 +575,6 @@
|
||||||
(clear-local-transform)
|
(clear-local-transform)
|
||||||
(dwsh/update-shapes ids update-shape))))))
|
(dwsh/update-shapes ids update-shape))))))
|
||||||
|
|
||||||
|
|
||||||
(defn set-selrect-transform
|
|
||||||
[modifiers]
|
|
||||||
(ptk/reify ::set-selrect-transform
|
|
||||||
ptk/UpdateEvent
|
|
||||||
(update [_ state]
|
|
||||||
(assoc state :workspace-selrect-transform (ctm/modifiers->transform modifiers)))))
|
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private
|
||||||
xf-rotation-shape
|
xf-rotation-shape
|
||||||
(comp
|
(comp
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
[app.main.data.workspace.modifiers :as dwm]
|
[app.main.data.workspace.modifiers :as dwm]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[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.undo :as dwu]
|
||||||
[app.main.features :as features]
|
[app.main.features :as features]
|
||||||
[app.main.fonts :as fonts]
|
[app.main.fonts :as fonts]
|
||||||
|
@ -945,14 +946,17 @@
|
||||||
new-shape))
|
new-shape))
|
||||||
{:undo-group (when new-shape? id)})
|
{:undo-group (when new-shape? id)})
|
||||||
|
|
||||||
(if finalize?
|
(if (and (not= :fixed (:grow-type shape)) finalize?)
|
||||||
(dwm/apply-wasm-modifiers
|
(dwm/apply-wasm-modifiers
|
||||||
(resize-wasm-text-modifiers shape content)
|
(resize-wasm-text-modifiers shape content)
|
||||||
{:undo-group (when new-shape? id)})
|
{:undo-group (when new-shape? id)})
|
||||||
|
|
||||||
(dwm/set-wasm-modifiers
|
(dwm/set-wasm-modifiers
|
||||||
(resize-wasm-text-modifiers shape content)
|
(resize-wasm-text-modifiers shape content)
|
||||||
{:undo-group (when new-shape? id)}))))
|
{:undo-group (when new-shape? id)}))
|
||||||
|
|
||||||
|
(when finalize?
|
||||||
|
(dwt/finish-transform))))
|
||||||
|
|
||||||
(let [objects (dsh/lookup-page-objects state)
|
(let [objects (dsh/lookup-page-objects state)
|
||||||
shape (get objects id)
|
shape (get objects id)
|
||||||
|
|
|
@ -136,7 +136,7 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(-> state
|
(-> state
|
||||||
(update :workspace-local dissoc :transform :duplicate-move-started?)
|
(update :workspace-local dissoc :transform :duplicate-move-started?)
|
||||||
(dissoc :workspace-selrect-transform)))))
|
(dissoc :workspace-selrect)))))
|
||||||
|
|
||||||
;; -- Resize --------------------------------------------------------
|
;; -- Resize --------------------------------------------------------
|
||||||
|
|
||||||
|
@ -296,7 +296,6 @@
|
||||||
(fn [modifiers]
|
(fn [modifiers]
|
||||||
(let [modif-tree (dwm/create-modif-tree ids modifiers)]
|
(let [modif-tree (dwm/create-modif-tree ids modifiers)]
|
||||||
(rx/of
|
(rx/of
|
||||||
(dwm/set-selrect-transform modifiers)
|
|
||||||
(dwm/set-wasm-modifiers
|
(dwm/set-wasm-modifiers
|
||||||
modif-tree
|
modif-tree
|
||||||
:ignore-constraints (contains? layout :scale-text))))))
|
:ignore-constraints (contains? layout :scale-text))))))
|
||||||
|
|
|
@ -147,9 +147,6 @@
|
||||||
(def workspace-drawing
|
(def workspace-drawing
|
||||||
(l/derived :workspace-drawing st/state))
|
(l/derived :workspace-drawing st/state))
|
||||||
|
|
||||||
(def workspace-selrect-transform
|
|
||||||
(l/derived :workspace-selrect-transform st/state))
|
|
||||||
|
|
||||||
(def workspace-tokens
|
(def workspace-tokens
|
||||||
"All tokens related ephimeral state"
|
"All tokens related ephimeral state"
|
||||||
(l/derived :workspace-tokens st/state))
|
(l/derived :workspace-tokens st/state))
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
[{:keys [shape zoom modifiers]}]
|
[{:keys [shape zoom modifiers]}]
|
||||||
(if (features/active-feature? @st/state "render-wasm/v1")
|
(if (features/active-feature? @st/state "render-wasm/v1")
|
||||||
(let [transform (gsh/transform-str shape)
|
(let [transform (gsh/transform-str shape)
|
||||||
{:keys [id x y]} shape
|
{:keys [id x y grow-type]} shape
|
||||||
{:keys [width height]} (wasm.api/text-dimensions id)]
|
{:keys [width height]} (if (= :fixed grow-type) shape (wasm.api/text-dimensions id))]
|
||||||
[:rect.main.viewport-selrect
|
[:rect.main.viewport-selrect
|
||||||
{:x x
|
{:x x
|
||||||
:y y
|
:y y
|
||||||
|
|
|
@ -16,9 +16,13 @@
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.texts :as dwt]
|
[app.main.data.workspace.texts :as dwt]
|
||||||
|
[app.main.features :as features]
|
||||||
|
[app.main.fonts :as fonts]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.css-cursors :as cur]
|
[app.main.ui.css-cursors :as cur]
|
||||||
|
[app.main.ui.hooks :as h]
|
||||||
|
[app.render-wasm.api :as wasm.api]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.globals :as global]
|
[app.util.globals :as global]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
|
@ -34,6 +38,20 @@
|
||||||
result (.-textContent editor-root)]
|
result (.-textContent editor-root)]
|
||||||
(when (not= result "") result))))
|
(when (not= result "") result))))
|
||||||
|
|
||||||
|
(defn- get-fonts
|
||||||
|
[content]
|
||||||
|
(let [extract-fn (juxt :font-id :font-variant-id)
|
||||||
|
default (extract-fn txt/default-text-attrs)]
|
||||||
|
(->> (tree-seq map? :children content)
|
||||||
|
(into #{default} (keep extract-fn)))))
|
||||||
|
|
||||||
|
(defn- load-fonts!
|
||||||
|
[fonts]
|
||||||
|
(->> fonts
|
||||||
|
(run! (fn [[font-id variant-id]]
|
||||||
|
(when (some? font-id)
|
||||||
|
(fonts/ensure-loaded! font-id variant-id))))))
|
||||||
|
|
||||||
(defn- initialize-event-handlers
|
(defn- initialize-event-handlers
|
||||||
"Internal editor events handler initializer/destructor"
|
"Internal editor events handler initializer/destructor"
|
||||||
[shape-id content selection-ref editor-ref container-ref]
|
[shape-id content selection-ref editor-ref container-ref]
|
||||||
|
@ -137,7 +155,14 @@
|
||||||
|
|
||||||
;; This reference is to the container
|
;; This reference is to the container
|
||||||
container-ref (mf/use-ref nil)
|
container-ref (mf/use-ref nil)
|
||||||
selection-ref (mf/use-ref nil)]
|
selection-ref (mf/use-ref nil)
|
||||||
|
|
||||||
|
fonts
|
||||||
|
(-> (mf/use-memo (mf/deps content) #(get-fonts content))
|
||||||
|
(h/use-equal-memo))]
|
||||||
|
|
||||||
|
(mf/with-effect [fonts]
|
||||||
|
(load-fonts! fonts))
|
||||||
|
|
||||||
;; WARN: we explicitly do not pass content on effect dependency
|
;; WARN: we explicitly do not pass content on effect dependency
|
||||||
;; array because we only need to initialize this once with initial
|
;; array because we only need to initialize this once with initial
|
||||||
|
@ -235,16 +260,24 @@
|
||||||
(some? modifiers)
|
(some? modifiers)
|
||||||
(gsh/transform-shape modifiers))
|
(gsh/transform-shape modifiers))
|
||||||
|
|
||||||
bounds (gst/shape->rect shape)
|
[x y width height]
|
||||||
|
(if (features/active-feature? @st/state "render-wasm/v1")
|
||||||
|
(let [{:keys [width height]} (wasm.api/text-dimensions shape-id)
|
||||||
|
{:keys [x y]} (:selrect shape)]
|
||||||
|
|
||||||
|
[x y width height])
|
||||||
|
|
||||||
|
(let [bounds (gst/shape->rect shape)
|
||||||
|
x (mth/min (dm/get-prop bounds :x)
|
||||||
|
(dm/get-prop shape :x))
|
||||||
|
y (mth/min (dm/get-prop bounds :y)
|
||||||
|
(dm/get-prop shape :y))
|
||||||
|
width (mth/max (dm/get-prop bounds :width)
|
||||||
|
(dm/get-prop shape :width))
|
||||||
|
height (mth/max (dm/get-prop bounds :height)
|
||||||
|
(dm/get-prop shape :height))]
|
||||||
|
[x y width height]))
|
||||||
|
|
||||||
x (mth/min (dm/get-prop bounds :x)
|
|
||||||
(dm/get-prop shape :x))
|
|
||||||
y (mth/min (dm/get-prop bounds :y)
|
|
||||||
(dm/get-prop shape :y))
|
|
||||||
width (mth/max (dm/get-prop bounds :width)
|
|
||||||
(dm/get-prop shape :width))
|
|
||||||
height (mth/max (dm/get-prop bounds :height)
|
|
||||||
(dm/get-prop shape :height))
|
|
||||||
style
|
style
|
||||||
(cond-> #js {:pointerEvents "all"}
|
(cond-> #js {:pointerEvents "all"}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
[app.util.debug :as dbg]
|
[app.util.debug :as dbg]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def rotation-handler-size 20)
|
(def rotation-handler-size 20)
|
||||||
|
@ -313,17 +314,23 @@
|
||||||
:style {:fill (if (dbg/enabled? :handlers) "yellow" "none")
|
:style {:fill (if (dbg/enabled? :handlers) "yellow" "none")
|
||||||
:stroke-width 0}}]]))
|
:stroke-width 0}}]]))
|
||||||
|
|
||||||
|
(def workspace-selrect-transform
|
||||||
|
(l/derived :workspace-selrect st/state))
|
||||||
|
|
||||||
|
(defn get-selrect
|
||||||
|
[selrect-transform shape]
|
||||||
|
(if (some? selrect-transform)
|
||||||
|
(let [{:keys [center width height transform]} selrect-transform]
|
||||||
|
[(gsh/center->rect center width height)
|
||||||
|
(gmt/transform-in center transform)])
|
||||||
|
[(dm/get-prop shape :selrect)
|
||||||
|
(gsh/transform-matrix shape)]))
|
||||||
|
|
||||||
(mf/defc controls-selection*
|
(mf/defc controls-selection*
|
||||||
[{:keys [shape zoom color on-move-selected on-context-menu disabled]}]
|
[{:keys [shape zoom color on-move-selected on-context-menu disabled]}]
|
||||||
(let [selrect (dm/get-prop shape :selrect)
|
(let [selrect-transform (mf/deref workspace-selrect-transform)
|
||||||
transform-type (mf/deref refs/current-transform)
|
transform-type (mf/deref refs/current-transform)
|
||||||
sr-transform (mf/deref refs/workspace-selrect-transform)
|
[selrect transform] (get-selrect selrect-transform shape)]
|
||||||
|
|
||||||
transform
|
|
||||||
(dm/str
|
|
||||||
(cond->> (gsh/transform-matrix shape)
|
|
||||||
(some? sr-transform)
|
|
||||||
(gmt/multiply sr-transform)))]
|
|
||||||
|
|
||||||
(when (and (some? selrect)
|
(when (and (some? selrect)
|
||||||
(not (or (= transform-type :move)
|
(not (or (= transform-type :move)
|
||||||
|
@ -340,19 +347,15 @@
|
||||||
(mf/defc controls-handlers*
|
(mf/defc controls-handlers*
|
||||||
{::mf/private true}
|
{::mf/private true}
|
||||||
[{:keys [shape zoom color on-resize on-rotate disabled]}]
|
[{:keys [shape zoom color on-resize on-rotate disabled]}]
|
||||||
(let [transform-type (mf/deref refs/current-transform)
|
(let [selrect-transform (mf/deref workspace-selrect-transform)
|
||||||
sr-transform (mf/deref refs/workspace-selrect-transform)
|
transform-type (mf/deref refs/current-transform)
|
||||||
|
|
||||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
|
|
||||||
layout (mf/deref refs/workspace-layout)
|
layout (mf/deref refs/workspace-layout)
|
||||||
scale-text? (contains? layout :scale-text)
|
scale-text? (contains? layout :scale-text)
|
||||||
|
|
||||||
selrect (dm/get-prop shape :selrect)
|
[selrect transform] (get-selrect selrect-transform shape)
|
||||||
|
|
||||||
transform (cond->> (gsh/transform-matrix shape)
|
|
||||||
(some? sr-transform)
|
|
||||||
(gmt/multiply sr-transform))
|
|
||||||
|
|
||||||
rotation (-> (gpt/point 1 0)
|
rotation (-> (gpt/point 1 0)
|
||||||
(gpt/transform (:transform shape))
|
(gpt/transform (:transform shape))
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
["react-dom/server" :as rds]
|
["react-dom/server" :as rds]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.geom.matrix :as gmt]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.types.path :as path]
|
[app.common.types.path :as path]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
@ -808,8 +810,29 @@
|
||||||
(sr/heapu32-set-uuid id heapu32 current-offset)
|
(sr/heapu32-set-uuid id heapu32 current-offset)
|
||||||
(sr/heapf32-set-matrix transform heapf32 (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-TRANSFORM-OFFSET)))
|
(sr/heapf32-set-matrix transform heapf32 (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-TRANSFORM-OFFSET)))
|
||||||
(recur (rest entries) (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-SIZE))))))
|
(recur (rest entries) (+ current-offset (mem/ptr8->ptr32 MODIFIER-ENTRY-SIZE))))))
|
||||||
(h/call wasm/internal-module "_propagate_apply")
|
|
||||||
(request-render "set-modifiers"))))
|
(let [offset (h/call wasm/internal-module "_propagate_apply")
|
||||||
|
heapf32 (mem/get-heap-f32)
|
||||||
|
width (aget heapf32 (mem/ptr8->ptr32 (+ offset 0)))
|
||||||
|
height (aget heapf32 (mem/ptr8->ptr32 (+ offset 4)))
|
||||||
|
cx (aget heapf32 (mem/ptr8->ptr32 (+ offset 8)))
|
||||||
|
cy (aget heapf32 (mem/ptr8->ptr32 (+ offset 12)))
|
||||||
|
|
||||||
|
a (aget heapf32 (mem/ptr8->ptr32 (+ offset 16)))
|
||||||
|
b (aget heapf32 (mem/ptr8->ptr32 (+ offset 20)))
|
||||||
|
c (aget heapf32 (mem/ptr8->ptr32 (+ offset 24)))
|
||||||
|
d (aget heapf32 (mem/ptr8->ptr32 (+ offset 28)))
|
||||||
|
e (aget heapf32 (mem/ptr8->ptr32 (+ offset 32)))
|
||||||
|
f (aget heapf32 (mem/ptr8->ptr32 (+ offset 36)))
|
||||||
|
transform (gmt/matrix a b c d e f)]
|
||||||
|
|
||||||
|
(h/call wasm/internal-module "_free_bytes")
|
||||||
|
(request-render "set-modifiers")
|
||||||
|
|
||||||
|
{:width width
|
||||||
|
:height height
|
||||||
|
:center (gpt/point cx cy)
|
||||||
|
:transform transform}))))
|
||||||
|
|
||||||
(defn set-canvas-background
|
(defn set-canvas-background
|
||||||
[background]
|
[background]
|
||||||
|
|
|
@ -20,6 +20,7 @@ use crate::shapes::{BoolType, ConstraintH, ConstraintV, StructureEntry, Transfor
|
||||||
use crate::utils::uuid_from_u32_quartet;
|
use crate::utils::uuid_from_u32_quartet;
|
||||||
use crate::uuid::Uuid;
|
use crate::uuid::Uuid;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
|
use math::{Bounds, Matrix};
|
||||||
use state::State;
|
use state::State;
|
||||||
|
|
||||||
pub(crate) static mut STATE: Option<Box<State>> = None;
|
pub(crate) static mut STATE: Option<Box<State>> = None;
|
||||||
|
@ -397,13 +398,13 @@ pub extern "C" fn propagate_modifiers() -> *mut u8 {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
with_state!(state, {
|
with_state!(state, {
|
||||||
let result = shapes::propagate_modifiers(state, entries);
|
let (result, _) = shapes::propagate_modifiers(state, &entries);
|
||||||
mem::write_vec(result)
|
mem::write_vec(result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn propagate_apply() {
|
pub extern "C" fn propagate_apply() -> *mut u8 {
|
||||||
let bytes = mem::bytes();
|
let bytes = mem::bytes();
|
||||||
|
|
||||||
let entries: Vec<_> = bytes
|
let entries: Vec<_> = bytes
|
||||||
|
@ -412,15 +413,42 @@ pub extern "C" fn propagate_apply() {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
with_state!(state, {
|
with_state!(state, {
|
||||||
let result = shapes::propagate_modifiers(state, entries);
|
let (result, bounds) = shapes::propagate_modifiers(state, &entries);
|
||||||
|
|
||||||
for entry in result {
|
for entry in result {
|
||||||
state.modifiers.insert(entry.id, entry.transform);
|
state.modifiers.insert(entry.id, entry.transform);
|
||||||
}
|
}
|
||||||
state.rebuild_modifier_tiles();
|
state.rebuild_modifier_tiles();
|
||||||
});
|
|
||||||
|
|
||||||
mem::free_bytes();
|
mem::free_bytes();
|
||||||
|
|
||||||
|
let bbs: Vec<_> = entries.iter().flat_map(|e| bounds.get(&e.id)).collect();
|
||||||
|
|
||||||
|
let result_bound = if bbs.len() == 1 {
|
||||||
|
bbs[0]
|
||||||
|
} else {
|
||||||
|
&Bounds::join_bounds(&bbs)
|
||||||
|
};
|
||||||
|
|
||||||
|
let width = result_bound.width();
|
||||||
|
let height = result_bound.height();
|
||||||
|
let center = result_bound.center();
|
||||||
|
let transform = result_bound.transform_matrix().unwrap_or(Matrix::default());
|
||||||
|
|
||||||
|
let mut bytes = Vec::<u8>::with_capacity(40);
|
||||||
|
bytes.resize(40, 0);
|
||||||
|
bytes[0..4].clone_from_slice(&width.to_le_bytes());
|
||||||
|
bytes[4..8].clone_from_slice(&height.to_le_bytes());
|
||||||
|
bytes[8..12].clone_from_slice(¢er.x.to_le_bytes());
|
||||||
|
bytes[12..16].clone_from_slice(¢er.y.to_le_bytes());
|
||||||
|
bytes[16..20].clone_from_slice(&transform[0].to_le_bytes());
|
||||||
|
bytes[20..24].clone_from_slice(&transform[3].to_le_bytes());
|
||||||
|
bytes[24..28].clone_from_slice(&transform[1].to_le_bytes());
|
||||||
|
bytes[28..32].clone_from_slice(&transform[4].to_le_bytes());
|
||||||
|
bytes[32..36].clone_from_slice(&transform[2].to_le_bytes());
|
||||||
|
bytes[36..40].clone_from_slice(&transform[5].to_le_bytes());
|
||||||
|
return mem::write_bytes(bytes);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
@ -64,6 +64,29 @@ impl Bounds {
|
||||||
Self { nw, ne, se, sw }
|
Self { nw, ne, se, sw }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn join_bounds(bounds: &Vec<&Bounds>) -> Self {
|
||||||
|
let (min_x, min_y, max_x, max_y) =
|
||||||
|
bounds
|
||||||
|
.iter()
|
||||||
|
.fold((f32::MAX, f32::MAX, f32::MIN, f32::MIN), {
|
||||||
|
|(min_x, min_y, max_x, max_y), bound| {
|
||||||
|
(
|
||||||
|
f32::min(bound.min_x(), min_x),
|
||||||
|
f32::min(bound.min_y(), min_y),
|
||||||
|
f32::max(bound.max_x(), max_x),
|
||||||
|
f32::max(bound.max_y(), max_y),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self::new(
|
||||||
|
Point::new(min_x, min_y),
|
||||||
|
Point::new(max_x, min_y),
|
||||||
|
Point::new(max_x, max_y),
|
||||||
|
Point::new(min_x, max_y),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn horizontal_vec(&self) -> Vector {
|
pub fn horizontal_vec(&self) -> Vector {
|
||||||
Vector::new_points(&self.nw, &self.ne)
|
Vector::new_points(&self.nw, &self.ne)
|
||||||
}
|
}
|
||||||
|
@ -249,7 +272,10 @@ impl Bounds {
|
||||||
|
|
||||||
pub fn center(&self) -> Point {
|
pub fn center(&self) -> Point {
|
||||||
// Calculates the centroid of the four points
|
// Calculates the centroid of the four points
|
||||||
Point::new(self.nw.x + self.se.x / 2.0, self.nw.y + self.se.y / 2.0)
|
Point::new(
|
||||||
|
self.nw.x + (self.se.x - self.nw.x) / 2.0,
|
||||||
|
self.nw.y + (self.se.y - self.nw.y) / 2.0,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_matrix(&self) -> Option<Matrix> {
|
pub fn transform_matrix(&self) -> Option<Matrix> {
|
||||||
|
@ -297,11 +323,23 @@ impl Bounds {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_rect(&self) -> Rect {
|
pub fn to_rect(&self) -> Rect {
|
||||||
let minx = self.nw.x.min(self.ne.x).min(self.sw.x).min(self.se.x);
|
Rect::from_ltrb(self.min_x(), self.min_y(), self.max_x(), self.max_y())
|
||||||
let miny = self.nw.y.min(self.ne.y).min(self.sw.y).min(self.se.y);
|
}
|
||||||
let maxx = self.nw.x.max(self.ne.x).max(self.sw.x).max(self.se.x);
|
|
||||||
let maxy = self.nw.y.max(self.ne.y).max(self.sw.y).max(self.se.y);
|
pub fn min_x(&self) -> f32 {
|
||||||
Rect::from_ltrb(minx, miny, maxx, maxy)
|
self.nw.x.min(self.ne.x).min(self.sw.x).min(self.se.x)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min_y(&self) -> f32 {
|
||||||
|
self.nw.y.min(self.ne.y).min(self.sw.y).min(self.se.y)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_x(&self) -> f32 {
|
||||||
|
self.nw.x.max(self.ne.x).max(self.sw.x).max(self.se.x)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_y(&self) -> f32 {
|
||||||
|
self.nw.y.max(self.ne.y).max(self.sw.y).max(self.se.y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,10 @@ fn calculate_group_bounds(
|
||||||
shape_bounds.from_points(result)
|
shape_bounds.from_points(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec<TransformEntry> {
|
pub fn propagate_modifiers(
|
||||||
|
state: &State,
|
||||||
|
modifiers: &Vec<TransformEntry>,
|
||||||
|
) -> (Vec<TransformEntry>, HashMap<Uuid, Bounds>) {
|
||||||
let shapes = &state.shapes;
|
let shapes = &state.shapes;
|
||||||
|
|
||||||
let font_col = state.render_state.fonts.font_collection();
|
let font_col = state.render_state.fonts.font_collection();
|
||||||
|
@ -306,10 +309,13 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
layout_reflows = Vec::new();
|
layout_reflows = Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
modifiers
|
(
|
||||||
.iter()
|
modifiers
|
||||||
.map(|(key, val)| TransformEntry::new(*key, *val))
|
.iter()
|
||||||
.collect()
|
.map(|(key, val)| TransformEntry::new(*key, *val))
|
||||||
|
.collect(),
|
||||||
|
bounds,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -47,15 +47,11 @@ pub extern "C" fn get_text_dimensions() -> *mut u8 {
|
||||||
height = shape.selrect.height();
|
height = shape.selrect.height();
|
||||||
|
|
||||||
if let Type::Text(content) = &shape.shape_type {
|
if let Type::Text(content) = &shape.shape_type {
|
||||||
|
let paragraphs = content.get_skia_paragraphs(font_col);
|
||||||
|
height = auto_height(¶graphs).ceil();
|
||||||
match content.grow_type() {
|
match content.grow_type() {
|
||||||
GrowType::AutoWidth => {
|
GrowType::AutoWidth => {
|
||||||
let paragraphs = content.get_skia_paragraphs(font_col);
|
width = auto_width(¶graphs).ceil();
|
||||||
width = auto_width(¶graphs);
|
|
||||||
height = auto_height(¶graphs);
|
|
||||||
}
|
|
||||||
GrowType::AutoHeight => {
|
|
||||||
let paragraphs = content.get_skia_paragraphs(font_col);
|
|
||||||
height = auto_height(¶graphs);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue