0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-24 07:29:08 -05:00

🐛 Fix problems with old texts

This commit is contained in:
alonso.torres 2022-02-24 14:04:43 +01:00
parent ec63d23666
commit 64ffa9bb3f
10 changed files with 107 additions and 77 deletions

View file

@ -224,7 +224,7 @@
:internal.shape.text.position-data/font-size
:internal.shape.text.position-data/font-style
:internal.shape.text.position-data/font-weight
:internal.shape.text.position-data/rtl?
:internal.shape.text.position-data/rtl
:internal.shape.text.position-data/text
:internal.shape.text.position-data/text-decoration
:internal.shape.text.position-data/text-transform]
@ -243,7 +243,7 @@
(s/def :internal.shape.text.position-data/font-size string?)
(s/def :internal.shape.text.position-data/font-style string?)
(s/def :internal.shape.text.position-data/font-weight string?)
(s/def :internal.shape.text.position-data/rtl? boolean?)
(s/def :internal.shape.text.position-data/rtl boolean?)
(s/def :internal.shape.text.position-data/text string?)
(s/def :internal.shape.text.position-data/text-decoration string?)
(s/def :internal.shape.text.position-data/text-transform string?)

View file

@ -117,13 +117,31 @@
;; --- Helpers
(defn to-new-fills
[data]
[(d/without-nils (select-keys data [:fill-color :fill-opacity :fill-color-gradient :fill-color-ref-id :fill-color-ref-file]))])
(defn- shape-current-values
[shape pred attrs]
(let [root (:content shape)
nodes (->> (txt/node-seq pred root)
(map #(if (txt/is-text-node? %)
(merge txt/default-text-attrs %)
%)))]
(map (fn [node]
(if (txt/is-text-node? node)
(let [fills
(cond
(or (some? (:fill-color node))
(some? (:fill-opacity node))
(some? (:fill-color-gradient node)))
(to-new-fills node)
(some? (:fills node))
(:fills node)
:else
(:fills txt/default-text-attrs))]
(-> (merge txt/default-text-attrs node)
(assoc :fills fills)))
node))))]
(attrs/get-attrs-multi nodes attrs)))
(defn current-root-values
@ -140,8 +158,10 @@
(defn current-text-values
[{:keys [editor-state attrs shape]}]
(if editor-state
(-> (ted/get-editor-current-inline-styles editor-state)
(select-keys attrs))
(let [result (-> (ted/get-editor-current-inline-styles editor-state)
(select-keys attrs))
result (if (empty? result) txt/default-text-attrs result)]
result)
(shape-current-values shape txt/is-text-node? attrs)))
@ -220,24 +240,27 @@
(cph/group-shape? shape) (cph/get-children-ids objects id))]
(rx/of (dch/update-shapes shape-ids #(update-text-content % update-node? attrs/merge attrs))))))))
(defn migrate-node
[node]
(let [color-attrs (select-keys node [:fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient])]
(cond-> node
(d/not-empty? color-attrs)
(-> (dissoc :fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient)
(assoc :fills [color-attrs]))
(nil? (:fills node))
(assoc :fills (:fills txt/default-text-attrs)))))
(defn migrate-content
[content]
(txt/transform-nodes
#(or (txt/is-text-node? %) (txt/is-paragraph-node? %))
(fn [node]
(let [color-attrs (select-keys node [:fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient])]
(cond-> node
(d/not-empty? color-attrs)
(-> (dissoc :fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient)
(assoc :fills [color-attrs])))))
content))
(txt/transform-nodes (some-fn txt/is-text-node? txt/is-paragraph-node?) migrate-node content))
(defn update-text-with-function
[id update-node-fn]
(ptk/reify ::update-text-with-function
ptk/UpdateEvent
(update [_ state]
(d/update-in-when state [:workspace-editor-state id] ted/update-editor-current-inline-styles-fn update-node-fn))
(d/update-in-when state [:workspace-editor-state id] ted/update-editor-current-inline-styles-fn (comp update-node-fn migrate-node)))
ptk/WatchEvent
(watch [_ state _]
@ -245,10 +268,7 @@
(let [objects (wsh/lookup-page-objects state)
shape (get objects id)
update-node?
(fn [node]
(or (txt/is-text-node? node)
(txt/is-paragraph-node? node)))
update-node? (some-fn txt/is-text-node? txt/is-paragraph-node?)
shape-ids
(cond

View file

@ -48,11 +48,10 @@
(mf/set-ref-val! prev-obs-ref mutation-obs)
(.observe mutation-obs node options))))))]
(mf/use-effect
(fn []
(fn []
(when-let [^js prev-obs (mf/ref-val prev-obs-ref)]
(.disconnect prev-obs)
(mf/set-ref-val! prev-obs-ref nil)))))
(mf/with-effect
(fn []
(when-let [^js prev-obs (mf/ref-val prev-obs-ref)]
(.disconnect prev-obs)
(mf/set-ref-val! prev-obs-ref nil))))
[node-ref set-node]))

View file

@ -6,6 +6,7 @@
(ns app.main.ui.render
(:require
[app.common.data :as d]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
@ -92,12 +93,11 @@
(mf/with-memo [objects]
(render/shape-wrapper-factory objects))
text-shapes
(->> objects
(filter (fn [[_ shape]] (= :text (:type shape))))
(mapv second))
is-text? (fn [shape] (= :text (:type shape)))
render-texts? (and render-texts? (some #(nil? (:position-data %)) text-shapes))]
text-shapes (sequence (comp (map second) (filter is-text?)) objects)
render-texts? (and render-texts? (d/seek (comp nil? :position-data) text-shapes))]
(mf/with-effect [width height]
(dom/set-page-style {:size (str (mth/ceil width) "px "

View file

@ -89,11 +89,11 @@
(cond
(contains? shape :fill-image)
(let [fill-image-id (str "fill-image-" render-id)]
{:fill (str/format "url(#%s)" fill-image-id)})
{:fill (str "url(#" fill-image-id ")")})
(contains? shape :fill-color-gradient)
(let [fill-color-gradient-id (str "fill-color-gradient_" render-id (if index (str "_" index) ""))]
{:fill (str/format "url(#%s)" fill-color-gradient-id)})
{:fill (str "url(#" fill-color-gradient-id ")")})
(contains? shape :fill-color)
{:fill (:fill-color shape)}

View file

@ -45,19 +45,18 @@
(= :path (:type shape))
(obj/set! "patternTransform" transform))]
[:*
(for [[_shape-index shape] (d/enumerate (or (:position-data shape) [shape]))]
(for [[shape-index shape] (d/enumerate (or (:position-data shape) [shape]))]
[:*
(for [[fill-index value] (-> (d/enumerate (:fills shape [])) reverse)]
(cond (some? (:fill-color-gradient value))
(case (d/name (:type (:fill-color-gradient value)))
"linear" [:> grad/linear-gradient #js {:id (str "fill-color-gradient_" render-id "_" fill-index)
:gradient (:fill-color-gradient value)
:shape shape}]
"radial" [:> grad/radial-gradient #js {:id (str "fill-color-gradient_" render-id "_" fill-index)
:gradient (:fill-color-gradient value)
:shape shape}]))))
(when (some? (:fill-color-gradient value))
(let [props #js {:id (str "fill-color-gradient_" render-id "_" fill-index)
:gradient (:fill-color-gradient value)
:shape shape}]
(case (d/name (:type (:fill-color-gradient value)))
"linear" [:> grad/linear-gradient props]
"radial" [:> grad/radial-gradient props]))))
(for [[shape-index shape] (d/enumerate (or (:position-data shape) [shape]))]
(let [fill-id (str "fill-" shape-index "-" render-id)]
[:> :pattern (-> (obj/clone pattern-attrs)
(obj/set! "id" fill-id))
@ -70,4 +69,4 @@
(when has-image
[:image {:xlinkHref (get embed uri uri)
:width width
:height height}])]]))]))))
:height height}])]])])))))

View file

@ -87,11 +87,22 @@
:caretColor (or text-color "black")
:overflowWrap "initial"}
base (-> base
(obj/set! "--fills" (transit/encode-str (:fills data)))
#_(obj/set! "--fill-color" fill-color)
#_(obj/set! "--fill-color-gradient" (transit/encode-str (:fill-color-gradient data)))
#_(obj/set! "--fill-opacity" fill-opacity))]
fills
(cond
(some? (:fills data))
(:fills data)
(or (some? (:fill-color data))
(some? (:fill-opacity data))
(some? (:fill-color-gradient data)))
[(d/without-nils (select-keys data [:fill-color :fill-opacity :fill-color-gradient :fill-color-ref-id :fill-color-ref-file]))]
(nil? (:fills data))
[{:fill-color "#000000" :fill-opacity 1}])
base (cond-> base
(some? fills)
(obj/set! "--fills" (transit/encode-str fills)))]
(when (and (string? letter-spacing)
(pos? (alength letter-spacing)))

View file

@ -57,10 +57,9 @@
:textTransform (:text-transform data)
:textDecoration (:text-decoration data)
:fontStyle (:font-style data)
:direction (if (:rtl? data) "rtl" "ltr")
:direction (if (:rtl data) "rtl" "ltr")
:whiteSpace "pre"}
(obj/set! "fill" (str "url(#fill-" index "-" render-id ")"))
#_(attrs/add-fill data (get-gradient-id index)))})]
(obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))})]
[:& shape-custom-stroke {:shape shape :index index}
[:> :text props (:text data)]]))]]))

View file

@ -131,25 +131,26 @@
sid-ref (mf/use-ref nil)
handle-change-foreign-object
(fn [node]
(when-let [position-data (utp/calc-position-data node)]
(let [parent (dom/get-parent node)
parent-transform (dom/get-attribute parent "transform")
node-transform (dom/get-attribute node "transform")
(mf/use-callback
(fn [node]
(when-let [position-data (utp/calc-position-data node)]
(let [parent (dom/get-parent node)
parent-transform (dom/get-attribute parent "transform")
node-transform (dom/get-attribute node "transform")
parent-mtx (usvg/parse-transform parent-transform)
node-mtx (usvg/parse-transform node-transform)
parent-mtx (usvg/parse-transform parent-transform)
node-mtx (usvg/parse-transform node-transform)
;; We need to see what transformation is applied in the DOM to reverse it
;; before calculating the position data
mtx (-> (gmt/multiply parent-mtx node-mtx)
(gmt/inverse))
;; We need to see what transformation is applied in the DOM to reverse it
;; before calculating the position data
mtx (-> (gmt/multiply parent-mtx node-mtx)
(gmt/inverse))
position-data
(->> position-data
(mapv #(merge % (-> (select-keys % [:x :y :width :height])
(gsh/transform-rect mtx)))))]
(reset! local-position-data position-data))))
position-data
(->> position-data
(mapv #(merge % (-> (select-keys % [:x :y :width :height])
(gsh/transform-rect mtx)))))]
(reset! local-position-data position-data)))))
[node-ref on-change-node] (use-mutable-observer handle-change-foreign-object)

View file

@ -22,9 +22,10 @@
(.setEnd range node end-i)
(.getClientRects range)))
;; TODO: Evaluate to change this function to Javascript
(defn parse-text-nodes
"Given a text node retrieves the rectangles for everyone of its paragraphs and its text."
[parent-node rtl? text-node]
[parent-node rtl text-node]
(let [content (.-textContent text-node)
text-size (.-length content)]
@ -45,7 +46,7 @@
;; If the rects increase means we're in a new paragraph
(if (> (.-length rects) 1)
(let [entry {:node parent-node
:position (dom/bounding-rect->rect (if rtl? (second rects) (first rects)))
:position (dom/bounding-rect->rect (if rtl (second rects) (first rects)))
:text current}]
(recur to-i to-i "" (conj result entry)))
(recur from-i (inc to-i) (str current (nth content to-i)) result)))))))
@ -86,9 +87,9 @@
(->> text-nodes
(mapcat
(fn [parent-node]
(let [rtl? (= "rtl" (.-dir (.-parentElement parent-node)))]
(let [rtl (= "rtl" (.-dir (.-parentElement parent-node)))]
(->> (.-childNodes parent-node)
(mapcat #(parse-text-nodes parent-node rtl? %))))))
(mapcat #(parse-text-nodes parent-node rtl %))))))
(mapv #(update % :position translate-rect))))))
(defn calc-position-data
@ -101,15 +102,15 @@
(->> text-data
(mapv (fn [{:keys [node position text]}]
(let [{:keys [x y width height]} position
rtl? (= "rtl" (.-dir (.-parentElement ^js node)))
rtl (= "rtl" (.-dir (.-parentElement ^js node)))
styles (js/getComputedStyle ^js node)
get (fn [prop]
(let [value (.getPropertyValue styles prop)]
(when (and value (not= value ""))
value)))]
(d/without-nils
{:rtl? rtl?
:x (if rtl? (+ x width) x)
{:rtl rtl
:x (if rtl (+ x width) x)
:y (+ y height)
:width width
:height height