diff --git a/CHANGES.md b/CHANGES.md index e4d45a2b91..43bc5cb008 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,5 @@ # CHANGELOG -<<<<<<< HEAD ## :rocket: Next ### :boom: Breaking changes & Deprecations @@ -24,6 +23,7 @@ - Improve behavior for undo on text edition [Taiga #4693](https://tree.taiga.io/project/penpot/issue/4693) - Improve deeps selection of nested arboards [Taiga #4913](https://tree.taiga.io/project/penpot/issue/4913) - Fix problem on selection numeric inputs on Firefox [#2991](https://github.com/penpot/penpot/issues/2991) +- Changed the text dominant-baseline to use ideographic [Taiga #4791](https://tree.taiga.io/project/penpot/issue/4791) ### :arrow_up: Deps updates @@ -31,8 +31,6 @@ - To @ondrejkonec: for contributing to the code with: - Refactor CSS variables [Github #2948](https://github.com/penpot/penpot/pull/2948) -======= ->>>>>>> origin/staging ## 1.17.3 ### :bug: Bugs fixed diff --git a/frontend/src/app/main/ui/shapes/text/svg_text.cljs b/frontend/src/app/main/ui/shapes/text/svg_text.cljs index 64edf85037..e508f0bbfc 100644 --- a/frontend/src/app/main/ui/shapes/text/svg_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/svg_text.cljs @@ -69,16 +69,21 @@ [:> :g group-props (for [[index data] (d/enumerate position-data)] - (let [alignment-bl (when (cf/check-browser? :safari) "text-before-edge") - dominant-bl (when-not (cf/check-browser? :safari) "text-before-edge") - rtl? (= "rtl" (:direction data)) + (let [rtl? (= "rtl" (:direction data)) + + browser-props + (cond + (cf/check-browser? :safari) + #js {:dominantBaseline "hanging" + :dy "0.2em" + :y (- (:y data) (:height data))}) + props (-> #js {:key (dm/str "text-" (:id shape) "-" index) :x (if rtl? (+ (:x data) (:width data)) (:x data)) - :y (- (:y data) (:height data)) + :y (:y data) + :dominantBaseline "ideographic" :textLength (:width data) :lengthAdjust "spacingAndGlyphs" - :alignmentBaseline alignment-bl - :dominantBaseline dominant-bl :style (-> #js {:fontFamily (:font-family data) :fontSize (:font-size data) :fontWeight (:font-weight data) @@ -88,7 +93,9 @@ :fontStyle (:font-style data) :direction (:direction data) :whiteSpace "pre"} - (obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))}) + (obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))} + (cond-> browser-props + (obj/merge! browser-props))) shape (assoc shape :fills (:fills data))] [:& (mf/provider muc/render-id) {:key index :value (str render-id "_" (:id shape) "_" index)} diff --git a/frontend/src/app/main/ui/workspace/shapes/text.cljs b/frontend/src/app/main/ui/workspace/shapes/text.cljs index 39ae91b1cf..d1d34b6c0c 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text.cljs @@ -15,9 +15,54 @@ [app.main.refs :as refs] [app.main.ui.shapes.shape :refer [shape-container]] [app.main.ui.shapes.text :as text] + [app.util.dom :as dom] [debug :refer [debug?]] [rumext.v2 :as mf])) +(mf/defc debug-text-bounds + {::mf/wrap-props false} + [props] + (let [shape (unchecked-get props "shape") + zoom (mf/deref refs/selected-zoom) + bounding-box (gsht/position-data-selrect shape) + ctx (js* "document.createElement(\"canvas\").getContext(\"2d\")")] + [:g {:transform (gsh/transform-str shape)} + [:rect {:x (:x bounding-box) + :y (:y bounding-box) + :width (:width bounding-box) + :height (:height bounding-box) + :style {:fill "none" + :stroke "orange" + :stroke-width (/ 1 zoom)}}] + + (for [[index data] (d/enumerate (:position-data shape))] + (let [{:keys [x y width height]} data + res (dom/measure-text ctx (:font-size data) (:font-family data) (:text data))] + [:g {:key (dm/str index)} + ;; Text fragment bounding box + [:rect {:x x + :y (- y height) + :width width + :height height + :style {:fill "none" + :stroke "red" + :stroke-width (/ 1 zoom)}}] + + ;; Text baseline + [:line {:x1 (mth/round x) + :y1 (mth/round (- (:y data) (:height data))) + :x2 (mth/round (+ x width)) + :y2 (mth/round (- (:y data) (:height data))) + :style {:stroke "blue" + :stroke-width (/ 1 zoom)}}] + + [:line {:x1 (:x data) + :y1 (- (:y data) (:descent res)) + :x2 (+ (:x data) (:width data)) + :y2 (- (:y data) (:descent res)) + :style {:stroke "green" + :stroke-width (/ 2 zoom)}}]]))])) + ;; --- Text Wrapper for workspace (mf/defc text-wrapper {::mf/wrap-props false} @@ -39,28 +84,4 @@ [:& text/text-shape {:shape shape}]] (when (and (debug? :text-outline) (d/not-empty? (:position-data shape))) - [:g {:transform (gsh/transform-str shape)} - (let [bounding-box (gsht/position-data-selrect shape)] - [:rect { - :x (:x bounding-box) - :y (:y bounding-box) - :width (:width bounding-box) - :height (:height bounding-box) - :style { :fill "none" :stroke "orange"}}]) - - (for [[index data] (d/enumerate (:position-data shape))] - (let [{:keys [x y width height]} data] - [:g {:key (dm/str index)} - ;; Text fragment bounding box - [:rect {:x x - :y (- y height) - :width width - :height height - :style {:fill "none" :stroke "red"}}] - - ;; Text baseline - [:line {:x1 (mth/round x) - :y1 (mth/round (- (:y data) (:height data))) - :x2 (mth/round (+ x width)) - :y2 (mth/round (- (:y data) (:height data))) - :style {:stroke "blue"}}]]))])])) + [:& debug-text-bounds {:shape shape}])])) diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index 3b15048edc..d6f0645463 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -662,3 +662,12 @@ (defn has-children? [^js node] (> (-> node .-children .-length) 0)) + +;; WARNING: Use only for debugging. It's to costly to use for real +(defn measure-text + "Given a canvas' context 2d and the text info returns tis ascent/descent info" + [context-2d font-size font-family text] + (let [_ (set! (.-font context-2d) (str font-size " " font-family)) + measures (.measureText context-2d text)] + {:descent (.-actualBoundingBoxDescent measures) + :ascent (.-actualBoundingBoxAscent measures)}))