mirror of
https://github.com/penpot/penpot.git
synced 2026-01-02 03:18:44 -05:00
Compare commits
1 Commits
develop
...
elenatorro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b4b807d14 |
@@ -10,6 +10,7 @@
|
||||
[app.common.data :as d]
|
||||
[app.main.data.exports.assets :as de]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.features :as features]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
@@ -17,6 +18,7 @@
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :as i]
|
||||
[app.main.ui.exports.assets]
|
||||
[app.render-wasm.api :as wasm.api]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :refer [c tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
@@ -52,6 +54,8 @@
|
||||
open* (mf/use-state true)
|
||||
open? (deref open*)
|
||||
|
||||
render-wasm? (features/use-feature "render-wasm/v1")
|
||||
|
||||
state (mf/deref refs/export)
|
||||
|
||||
in-progress?
|
||||
@@ -68,6 +72,8 @@
|
||||
(mf/with-memo [shapes]
|
||||
(filter (comp seq :exports) shapes))
|
||||
|
||||
render-wasm? (features/use-feature "render-wasm/v1")
|
||||
|
||||
sname
|
||||
(when (seqable? exports)
|
||||
(let [sname (-> shapes-with-exports first :name)
|
||||
@@ -86,39 +92,41 @@
|
||||
(mf/deps ids page-id file-id exports)
|
||||
(fn [event]
|
||||
(dom/prevent-default event)
|
||||
(if (= :multiple type)
|
||||
(if render-wasm?
|
||||
(wasm.api/download-as-png)
|
||||
(do (if (= :multiple type)
|
||||
;; I can select multiple shapes all of them with no export settings and one of them with only one
|
||||
;; In that situation we must export it directly
|
||||
(if (and (= 1 (count shapes-with-exports)) (= 1 (-> shapes-with-exports first :exports count)))
|
||||
(let [shape (-> shapes-with-exports first)
|
||||
export (-> shape :exports first)
|
||||
suffix (:suffix export)
|
||||
sname (cond-> (:name shape)
|
||||
(some? suffix)
|
||||
(str suffix))
|
||||
defaults {:page-id page-id
|
||||
:file-id file-id
|
||||
:name sname
|
||||
:object-id (:id (first shapes-with-exports))}
|
||||
full-export (merge export defaults)]
|
||||
(st/emit!
|
||||
(de/request-simple-export {:export full-export})
|
||||
(de/export-shapes-event [full-export] "workspace:sidebar")))
|
||||
(st/emit!
|
||||
(de/show-workspace-export-dialog {:selected (reverse ids) :origin "workspace:sidebar"})))
|
||||
(if (and (= 1 (count shapes-with-exports)) (= 1 (-> shapes-with-exports first :exports count)))
|
||||
(let [shape (-> shapes-with-exports first)
|
||||
export (-> shape :exports first)
|
||||
suffix (:suffix export)
|
||||
sname (cond-> (:name shape)
|
||||
(some? suffix)
|
||||
(str suffix))
|
||||
defaults {:page-id page-id
|
||||
:file-id file-id
|
||||
:name sname
|
||||
:object-id (:id (first shapes-with-exports))}
|
||||
full-export (merge export defaults)]
|
||||
(st/emit!
|
||||
(de/request-simple-export {:export full-export})
|
||||
(de/export-shapes-event [full-export] "workspace:sidebar")))
|
||||
(st/emit!
|
||||
(de/show-workspace-export-dialog {:selected (reverse ids) :origin "workspace:sidebar"})))
|
||||
|
||||
;; In other all cases we only allowed to have a single
|
||||
;; shape-id because multiple shape-ids are handled
|
||||
;; separately by the export-modal.
|
||||
(let [defaults {:page-id page-id
|
||||
:file-id file-id
|
||||
:name sname
|
||||
:object-id (first ids)}
|
||||
exports (mapv #(merge % defaults) exports)]
|
||||
(let [defaults {:page-id page-id
|
||||
:file-id file-id
|
||||
:name sname
|
||||
:object-id (first ids)}
|
||||
exports (mapv #(merge % defaults) exports)]
|
||||
|
||||
(st/emit!
|
||||
(de/request-export {:exports exports})
|
||||
(de/export-shapes-event exports "workspace:sidebar"))))))
|
||||
(st/emit!
|
||||
(de/request-export {:exports exports})
|
||||
(de/export-shapes-event exports "workspace:sidebar"))))))))
|
||||
|
||||
|
||||
;; TODO: maybe move to specific events for avoid to have this logic here?
|
||||
|
||||
@@ -678,6 +678,20 @@
|
||||
[grow-type]
|
||||
(h/call wasm/internal-module "_set_shape_grow_type" (sr/translate-grow-type grow-type)))
|
||||
|
||||
(defn download-as-png []
|
||||
[]
|
||||
(let [offset (-> (h/call wasm/internal-module "_download_png")
|
||||
(mem/->offset-32))
|
||||
heap (mem/get-heap-u32)
|
||||
length (aget heap offset)
|
||||
data (mem/slice heap
|
||||
(+ offset 1)
|
||||
(* length path.impl/SEGMENT-U32-SIZE))
|
||||
blob (js/Blob. #js [data] #js {:type "image/png"})
|
||||
url (js/URL.createObjectURL blob)]
|
||||
(mem/free)
|
||||
(js/window.open url "_blank")))
|
||||
|
||||
(defn get-text-dimensions
|
||||
([id]
|
||||
(use-shape id)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::performance;
|
||||
use crate::shapes::Shape;
|
||||
use crate::{mem, performance, with_current_shape, with_current_shape_mut, STATE};
|
||||
|
||||
use skia_safe::{self as skia, IRect, Paint, RRect};
|
||||
|
||||
@@ -411,3 +411,24 @@ impl TileTextureCache {
|
||||
self.grid.clear();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn download_png(_ptr: *const u8, _len: usize) -> *mut u8 {
|
||||
let mut png_bytes: Vec<u8> = Vec::new();
|
||||
unsafe {
|
||||
if let Some(state) = STATE.as_mut() {
|
||||
let png_base64 = state
|
||||
.render_state
|
||||
.surfaces
|
||||
.base64_snapshot(SurfaceId::Target);
|
||||
if let Ok(decoded) = general_purpose::STANDARD.decode(png_base64) {
|
||||
png_bytes = decoded;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut buffer = Vec::with_capacity(4 + png_bytes.len());
|
||||
buffer.extend_from_slice(&(png_bytes.len() as u32).to_le_bytes());
|
||||
buffer.extend_from_slice(&png_bytes);
|
||||
mem::write_bytes(buffer)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user