diff --git a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs index e611409192..4d80cac03c 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs @@ -309,7 +309,7 @@ [{:keys [x y width height]} transform] (if render-wasm? - (let [{:keys [width height]} (wasm.api/get-text-dimensions shape-id) + (let [{:keys [height]} (wasm.api/get-text-dimensions shape-id) selrect-transform (mf/deref refs/workspace-selrect) [selrect transform] (dsh/get-selrect selrect-transform shape) @@ -320,7 +320,7 @@ "bottom" (- y (- height (:height selrect))) "center" (- y (/ (- height (:height selrect)) 2)) y)] - [(assoc selrect :y y :width width :height height) transform]) + [(assoc selrect :y y :width (:width selrect) :height (:height selrect)) transform]) (let [bounds (gst/shape->rect shape) x (mth/min (dm/get-prop bounds :x) @@ -342,8 +342,8 @@ (not render-wasm?) (obj/merge! - #js {"--editor-container-width" (dm/str (:width shape) "px") - "--editor-container-height" (dm/str (:height shape) "px")}) + #js {"--editor-container-width" (dm/str width "px") + "--editor-container-height" (dm/str height "px")}) ;; Transform is necessary when there is a text overflow and the vertical ;; aligment is center or bottom. diff --git a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.scss b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.scss index 9300316961..feada220c0 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.scss +++ b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.scss @@ -8,6 +8,8 @@ .text-editor-container { height: 100%; position: relative; + + cursor: text; } .text-editor-selection-imposter { diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs index 650a3fe730..230abf8a28 100644 --- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs @@ -316,7 +316,7 @@ (not (contains? child-parent? %))) (and (features/active-feature? @st/state "render-wasm/v1") (cfh/text-shape? objects %) - (not (wasm.api/intersect-position % @last-point-ref))))))) + (not (wasm.api/intersect-position-in-shape % @last-point-ref))))))) remove-measure-xf (cond diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 7fd6960fad..aacd9b5cba 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -139,6 +139,7 @@ :shape-id id :dimensions (get-text-dimensions id)})) + (defn- ensure-text-content "Guarantee that the shape always sends a valid text tree to WASM. When the content is nil (freshly created text) we fall back to @@ -852,11 +853,11 @@ (mem/free) {:x x :y y :width width :height height :max-width max-width}))) -(defn intersect-position +(defn intersect-position-in-shape [id position] (let [buffer (uuid/get-u32 id) result - (h/call wasm/internal-module "_intersect_position" + (h/call wasm/internal-module "_intersect_position_in_shape" (aget buffer 0) (aget buffer 1) (aget buffer 2) diff --git a/render-wasm/src/shapes/text.rs b/render-wasm/src/shapes/text.rs index 380ac62106..7bc37c5f80 100644 --- a/render-wasm/src/shapes/text.rs +++ b/render-wasm/src/shapes/text.rs @@ -189,6 +189,7 @@ impl TextContentLayout { * Check if the current x,y (in paragraph relative coordinates) is inside * the paragraph */ +#[allow(dead_code)] fn intersects(paragraph: &skia_safe::textlayout::Paragraph, x: f32, y: f32) -> bool { if y < 0.0 || y > paragraph.height() { return false; @@ -693,7 +694,28 @@ impl TextContent { (fallback_width, fallback_height) } - pub fn intersect_position(&self, shape: &Shape, x_pos: f32, y_pos: f32) -> bool { + pub fn intersect_position_in_shape(&self, shape: &Shape, x_pos: f32, y_pos: f32) -> bool { + let rect = shape.selrect; + let mut matrix = Matrix::new_identity(); + let center = shape.center(); + let Some(inv_transform) = &shape.transform.invert() else { + return false; + }; + matrix.pre_translate(center); + matrix.pre_concat(inv_transform); + matrix.pre_translate(-center); + + let result = matrix.map_point((x_pos, y_pos)); + + let x_pos = result.x; + let y_pos = result.y; + + x_pos >= rect.x() && x_pos <= rect.right() && y_pos >= rect.y() && y_pos <= rect.bottom() + } + + // Leave this function for future use in the upcoming render editor + #[allow(dead_code)] + pub fn intersect_position_in_text(&self, shape: &Shape, x_pos: f32, y_pos: f32) -> bool { let rect = self.content_rect(&shape.selrect, shape.vertical_align); let mut matrix = Matrix::new_identity(); let center = shape.center(); diff --git a/render-wasm/src/wasm/text.rs b/render-wasm/src/wasm/text.rs index 9d6053af18..66e6c38cf6 100644 --- a/render-wasm/src/wasm/text.rs +++ b/render-wasm/src/wasm/text.rs @@ -341,7 +341,7 @@ pub extern "C" fn get_text_dimensions() -> *mut u8 { } #[no_mangle] -pub extern "C" fn intersect_position( +pub extern "C" fn intersect_position_in_shape( a: u32, b: u32, c: u32, @@ -355,7 +355,7 @@ pub extern "C" fn intersect_position( return false; }; if let Type::Text(content) = &shape.shape_type { - return content.intersect_position(shape, x_pos, y_pos); + return content.intersect_position_in_shape(shape, x_pos, y_pos); } }); false