From fef69cb707417901eaf2d5848f239c19c34b240a Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 11 May 2022 15:53:27 +0200 Subject: [PATCH] :bug: Fix problem with RTL texts --- frontend/src/app/main/ui/shapes/text/svg_text.cljs | 6 ++++-- frontend/src/app/util/text_position_data.js | 13 ++++--------- frontend/src/app/util/text_svg_position.cljs | 12 +++++++----- 3 files changed, 15 insertions(+), 16 deletions(-) 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 34e9cf5f3..24894825c 100644 --- a/frontend/src/app/main/ui/shapes/text/svg_text.cljs +++ b/frontend/src/app/main/ui/shapes/text/svg_text.cljs @@ -91,8 +91,9 @@ alignment-bl (when (cfg/check-browser? :safari) "text-before-edge") dominant-bl (when-not (cfg/check-browser? :safari) "ideographic") + rtl? (= "rtl"(:direction data)) props (-> #js {:key (dm/str "text-" (:id shape) "-" index) - :x (:x data) + :x (if rtl? (+ (:x data) (:width data)) (:x data)) :y y :transform (position-data-transform shape data) :alignmentBaseline alignment-bl @@ -104,7 +105,7 @@ :textDecoration (:text-decoration data) :letterSpacing (:letter-spacing data) :fontStyle (:font-style data) - :direction (if (:rtl data) "rtl" "ltr") + :direction (:direction data) :whiteSpace "pre"} (obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))}) shape (assoc shape :fills (:fills data))] @@ -112,3 +113,4 @@ [:& (mf/provider muc/render-ctx) {:value (str render-id "_" (:id shape) "_" index)} [:& shape-custom-strokes {:shape shape :key index} [:> :text props (:text data)]]]))]])) + diff --git a/frontend/src/app/util/text_position_data.js b/frontend/src/app/util/text_position_data.js index cb77fe8eb..40a18b3ba 100644 --- a/frontend/src/app/util/text_position_data.js +++ b/frontend/src/app/util/text_position_data.js @@ -21,27 +21,21 @@ goog.scope(function () { return range.getClientRects(); } - self.parse_text_nodes = function(parent, direction, textNode) { + self.parse_text_nodes = function(parent, textNode) { const content = textNode.textContent; const textSize = content.length; - const rtl = direction === "rtl"; let from = 0; let to = 0; let current = ""; let result = []; + let prevRect = null; while (to < textSize) { const rects = getRangeRects(textNode, from, to + 1); if (rects.length > 1) { - let position; - - if (rtl) { - position = rects[1]; - } else { - position = rects[0]; - } + const position = prevRect; result.push({ node: parent, @@ -53,6 +47,7 @@ goog.scope(function () { current = ""; } else { + prevRect = rects[0]; current += content[to]; to = to + 1; } diff --git a/frontend/src/app/util/text_svg_position.cljs b/frontend/src/app/util/text_svg_position.cljs index eff905a64..e25a70f6f 100644 --- a/frontend/src/app/util/text_svg_position.cljs +++ b/frontend/src/app/util/text_svg_position.cljs @@ -18,13 +18,14 @@ [parent-node direction text-node] (letfn [(parse-entry [^js entry] - {:node (.-node entry) - :position (dom/bounding-rect->rect (.-position entry)) - :text (.-text entry)})] + {:node (.-node entry) + :position (dom/bounding-rect->rect (.-position entry)) + :text (.-text entry) + :direction direction})] (into [] (map parse-entry) - (tpd/parse-text-nodes parent-node direction text-node)))) + (tpd/parse-text-nodes parent-node text-node)))) (defn calc-text-node-positions @@ -75,7 +76,7 @@ (let [text-data (calc-text-node-positions base-node viewport zoom)] (when (d/not-empty? text-data) (->> text-data - (mapv (fn [{:keys [node position text]}] + (mapv (fn [{:keys [node position text direction]}] (let [{:keys [x y width height]} position styles (js/getComputedStyle ^js node) get (fn [prop] @@ -87,6 +88,7 @@ :y (+ y height) :width width :height height + :direction direction :font-family (str (get "font-family")) :font-size (str (get "font-size")) :font-weight (str (get "font-weight"))