From 1d7c775f7207f706346b6233e49be0f0e89449c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Wed, 7 Oct 2026 12:26:45 +0200 Subject: [PATCH] :bug: Fix not setting mimetype in image fills (#12136) --- common/src/app/common/types/fills/impl.cljc | 42 ++++++++++++------- frontend/src/app/render_wasm/text_editor.cljs | 3 ++ render-wasm/src/shapes/fills.rs | 12 ++++++ render-wasm/src/wasm/fills.rs | 3 +- render-wasm/src/wasm/fills/image.rs | 5 ++- 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/common/src/app/common/types/fills/impl.cljc b/common/src/app/common/types/fills/impl.cljc index 2f8ca65a6f..453b95d6b3 100644 --- a/common/src/app/common/types/fills/impl.cljc +++ b/common/src/app/common/types/fills/impl.cljc @@ -59,6 +59,27 @@ result (bit-or result n)] result)) +(defn encode-mtype + "Encode an image media type as the 16-bit code shared with render-wasm." + [mtype] + (case mtype + "image/jpeg" 0x01 + "image/png" 0x02 + "image/gif" 0x03 + "image/webp" 0x04 + "image/svg+xml" 0x05 + 0x00)) + +(defn decode-mtype + [code] + (case code + 0x01 "image/jpeg" + 0x02 "image/png" + 0x03 "image/gif" + 0x04 "image/webp" + 0x05 "image/svg+xml" + nil)) + (defn- get-color-hex [n] (let [n (bit-and n 0x00ffffff) @@ -127,12 +148,13 @@ transform (get image :transform) has-transform? (some? transform) transform-flag (if has-transform? 0x02 0x00) - flags (bit-or keep-aspect-ratio transform-flag)] + flags (bit-or keep-aspect-ratio transform-flag) + mtype (encode-mtype (get image :mtype))] (buf/write-byte buffer (+ offset 0) 0x03) (buf/write-uuid buffer (+ offset 4) image-id) (buf/write-byte buffer (+ offset 20) alpha) (buf/write-byte buffer (+ offset 21) flags) - (buf/write-short buffer (+ offset 22) 0) ;; 2-byte padding (reserved for future use) + (buf/write-short buffer (+ offset 22) mtype) (buf/write-int buffer (+ offset 24) image-width) (buf/write-int buffer (+ offset 28) image-height) (if has-transform? @@ -155,13 +177,7 @@ mtype (dm/get-in fill [:fill-image :mtype])] (when mtype - (let [val (case mtype - "image/jpeg" 0x01 - "image/png" 0x02 - "image/gif" 0x03 - "image/webp" 0x04 - "image/svg+xml" 0x05)] - (buf/write-short buffer (+ offset 2) val))) + (buf/write-short buffer (+ offset 2) (encode-mtype mtype))) (if (and (some? ref-file) (some? ref-id)) @@ -235,13 +251,7 @@ :y (buf/read-float dbuffer (+ doffset 36)) :width (buf/read-float dbuffer (+ doffset 40)) :height (buf/read-float dbuffer (+ doffset 44))}) - mtype (buf/read-short mbuffer (+ moffset 2)) - mtype (case mtype - 0x01 "image/jpeg" - 0x02 "image/png" - 0x03 "image/gif" - 0x04 "image/webp" - 0x05 "image/svg+xml")] + mtype (decode-mtype (buf/read-short mbuffer (+ moffset 2)))] {:fill-opacity opacity :fill-image (cond-> {:id id :width width diff --git a/frontend/src/app/render_wasm/text_editor.cljs b/frontend/src/app/render_wasm/text_editor.cljs index ed82300c09..6493128aba 100644 --- a/frontend/src/app/render_wasm/text_editor.cljs +++ b/frontend/src/app/render_wasm/text_editor.cljs @@ -118,12 +118,15 @@ d (aget heap-u32 (+ fill-u32-offset 4)) alpha (aget heap-u8 (+ fill-byte-offset 20)) flags (aget heap-u8 (+ fill-byte-offset 21)) + mtype (bit-or (aget heap-u8 (+ fill-byte-offset 22)) + (bit-shift-left (aget heap-u8 (+ fill-byte-offset 23)) 8)) width (aget heap-i32 (+ fill-u32-offset 6)) height (aget heap-i32 (+ fill-u32-offset 7))] {:fill-opacity (u8->opacity alpha) :fill-image {:id (uuid/from-unsigned-parts a b c d) :width width :height height + :mtype (types.fills.impl/decode-mtype mtype) :keep-aspect-ratio (not (zero? (bit-and flags 0x01))) :name "sample"}}) diff --git a/render-wasm/src/shapes/fills.rs b/render-wasm/src/shapes/fills.rs index 94d33e7dd2..c819579de0 100644 --- a/render-wasm/src/shapes/fills.rs +++ b/render-wasm/src/shapes/fills.rs @@ -145,6 +145,8 @@ pub struct ImageFill { height: i32, keep_aspect_ratio: bool, transform: Option, + // Opaque media type code, kept so the frontend can read it back. + mtype: u16, } impl ImageFill { @@ -156,6 +158,7 @@ impl ImageFill { height, keep_aspect_ratio, transform: None, + mtype: 0, } } @@ -174,9 +177,14 @@ impl ImageFill { height, keep_aspect_ratio, transform, + mtype: 0, } } + pub fn with_mtype(self, mtype: u16) -> Self { + Self { mtype, ..self } + } + pub fn id(&self) -> Uuid { self.id } @@ -197,6 +205,10 @@ impl ImageFill { self.height } + pub fn mtype(&self) -> u16 { + self.mtype + } + pub fn transform(&self) -> Option<&ImageFillTransform> { self.transform.as_ref() } diff --git a/render-wasm/src/wasm/fills.rs b/render-wasm/src/wasm/fills.rs index 5d2a6e29e2..28ff005bec 100644 --- a/render-wasm/src/wasm/fills.rs +++ b/render-wasm/src/wasm/fills.rs @@ -179,7 +179,8 @@ mod tests { #[test] fn test_image_fill_round_trip() { - let image_fill = shapes::ImageFill::new(crate::uuid::Uuid::nil(), 0x80, 300, 200, true); + let image_fill = + shapes::ImageFill::new(crate::uuid::Uuid::nil(), 0x80, 300, 200, true).with_mtype(0x02); let fill = shapes::Fill::Image(image_fill); let raw_fill = RawFillData::try_from(&fill).expect("image fill must be serializable"); let bytes = <[u8; RAW_FILL_DATA_SIZE]>::from(raw_fill); diff --git a/render-wasm/src/wasm/fills/image.rs b/render-wasm/src/wasm/fills/image.rs index e6b2e634c5..86c9a12abe 100644 --- a/render-wasm/src/wasm/fills/image.rs +++ b/render-wasm/src/wasm/fills/image.rs @@ -44,7 +44,7 @@ pub struct RawImageFillData { d: u32, opacity: u8, flags: u8, - _pad: u16, + mtype: u16, width: i32, height: i32, transform_x: f32, @@ -76,7 +76,7 @@ impl From<&ImageFill> for RawImageFillData { d, opacity: image_fill.opacity(), flags, - _pad: 0, + mtype: image_fill.mtype(), width: image_fill.width(), height: image_fill.height(), transform_x: tx, @@ -110,6 +110,7 @@ impl From for ImageFill { keep_aspect_ratio, transform, ) + .with_mtype(value.mtype) } }