0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-15 03:28:25 -05:00

Draw colors from memory too

This commit is contained in:
Alejandro Alonso 2024-10-08 13:22:11 +02:00
parent 0027e77861
commit dc014bd4eb
5 changed files with 55 additions and 51 deletions

View file

@ -109,16 +109,6 @@ pub unsafe extern "C" fn resize_surface(state: *mut State, width: i32, height: i
state.set_surface(surface);
}
#[no_mangle]
pub extern "C" fn make_color(r: i32, g: i32, b: i32, a: f32) -> Box<Color> {
Box::new(Color {
r: r as u8,
g: g as u8,
b: b as u8,
a,
})
}
#[repr(C)]
pub struct Color {
r: u8,
@ -133,16 +123,10 @@ pub struct Rect {
top: f32,
right: f32,
bottom: f32,
}
#[no_mangle]
pub extern "C" fn make_rect(left: f32, top: f32, right: f32, bottom: f32) -> Box<Rect> {
Box::new(Rect {
left,
top,
right,
bottom,
})
r: f32,
g: f32,
b: f32,
a: f32,
}
#[no_mangle]
@ -156,6 +140,13 @@ pub extern "C" fn alloc_rects(len: usize) -> *mut Rect {
return ptr;
}
#[no_mangle]
pub unsafe fn free_rects(ptr: *mut Rect, len: usize) {
let buf = Vec::<Rect>::from_raw_parts(ptr, len, len);
std::mem::forget(buf);
}
/// Draws a rect at the specified coordinates with the give ncolor
/// # Safety
#[no_mangle]
@ -163,7 +154,6 @@ pub unsafe extern "C" fn draw_rect(state: *mut State, rect: &Rect, color: &Color
let state = unsafe { state.as_mut() }.expect("got an invalid state pointer");
let r = skia::Rect::new(rect.left, rect.top, rect.right, rect.bottom);
let color = skia::Color::from_argb((color.a * 255.0) as u8, color.r, color.g, color.b);
render_rect(&mut state.surface, r, color);
}
@ -201,7 +191,7 @@ pub unsafe fn draw_shapes(state: *mut State, ptr: *mut Rect, len: usize, zoom: f
let buf = Vec::<Rect>::from_raw_parts(ptr, len, len);
for rect in buf.iter() {
let r = skia::Rect::new(rect.left, rect.top, rect.right, rect.bottom);
let color = skia::Color::from_argb(255, 0, 0, 0);
let color = skia::Color::from_argb((rect.a * 255.0) as u8, rect.r as u8, rect.g as u8, rect.b as u8);
render_rect(&mut state.surface, r, color);
}
flush(state);

View file

@ -283,11 +283,14 @@
;; redraw when vbox or shapes change
(mf/with-effect
[vbox base-objects canvas-init? zoom]
(js/console.log "jibiri")
[vbox canvas-init? zoom]
(when (mf/ref-val canvas-init?)
(js/console.log "jibiri ho")
(render-v2/draw-canvas vbox zoom base-objects))))
(render-v2/draw-canvas vbox zoom base-objects)))
(mf/with-effect
[base-objects]
(when (mf/ref-val canvas-init?)
(render-v2/set-objects vbox zoom base-objects))))
(hooks/setup-dom-events zoom disable-paste in-viewport? workspace-read-only? drawing-tool drawing-path?)
(hooks/setup-viewport-size vport viewport-ref)

View file

@ -42,3 +42,9 @@
;; Rust
(contains? cf/flags :render-v2-rs)
(render-v2-rs/draw-canvas vbox zoom base-objects)))
(defn set-objects [vbox zoom base-objects]
(cond
;; Rust
(contains? cf/flags :render-v2-rs)
(render-v2-rs/set-objects vbox zoom base-objects)))

View file

@ -29,6 +29,32 @@
(js/requestAnimationFrame (fn []
(draw-shapes gpu-state shapes-ptr shapes-size zoom (- (:x vbox)) (- (:y vbox)))))))
(defn set-objects
[vbox zoom objects]
(let [alloc-rects (gobj/get ^js internal-module "_alloc_rects")
free_rects (gobj/get ^js internal-module "_free_rects")
supported-shapes (filter (fn [shape] (not= (:type shape) :frame)) (vals objects))
heap (gobj/get ^js internal-module "HEAPF32")
;; Each F32 are 4 bytes
;; Each rect has:
;; - 4 F32 for points coordinates
;; - 4 F32 for color
;; rect-size (* 8 4)
rect-size (* 8 4)]
(when shapes-ptr
(free_rects shapes-ptr shapes-size))
(let [ptr (alloc-rects (count supported-shapes))]
(doseq [[shape index] (zipmap supported-shapes (range))]
(let [sr (:selrect shape)
[r g b] (cc/hex->rgb (-> shape :fills first :fill-color))
alpha (-> shape :fills first :fill-opacity)
mem (js/Float32Array. (.-buffer heap) (+ ptr (* rect-size index)) rect-size)]
(set! shapes-ptr ptr)
(set! shapes-size (count supported-shapes))
(.set mem (js/Float32Array. (clj->js [(:x1 sr) (:y1 sr) (:x2 sr) (:y2 sr) r g b (or alpha 1)]))))))
(draw-canvas vbox zoom objects)))
(defn set-canvas
[canvas vbox zoom objects]
(let [gl (gobj/get ^js internal-module "GL")
@ -40,32 +66,12 @@
handle (.registerContext gl context {"majorVersion" 2})
_ (.makeContextCurrent gl handle)
;; Initialize Skia
state (._init ^js internal-module (.-width canvas) (.-height canvas))
translate (gobj/get ^js internal-module "_translate")
scale (gobj/get ^js internal-module "_scale")
alloc-rects (gobj/get ^js internal-module "_alloc_rects")
heap (gobj/get ^js internal-module "HEAPF32")
supported-shapes (filter (fn [shape] (not= (:type shape) :frame)) (vals objects))
ptr (alloc-rects (count supported-shapes))]
state (._init ^js internal-module (.-width canvas) (.-height canvas))]
(set! (.-width canvas) (.-clientWidth canvas))
(set! (.-height canvas) (.-clientHeight canvas))
(set! gpu-state state)
(set! shapes-ptr ptr)
(set! shapes-size (count supported-shapes))
(doseq [[shape index] (zipmap supported-shapes (range))]
(let [sr (:selrect shape)
[r g b] (cc/hex->rgb (-> shape :fills first :fill-color))
alpha (-> shape :fills first :fill-opacity)
;; color (make-color r g b alpha)
;; rect (make-rect (:x1 sr) (:y1 sr) (:x2 sr) (:y2 sr))
;; Each F32 are 4 bytes and each rect has 4 F32
mem (js/Float32Array. (.-buffer heap) (+ ptr (* (* 4 4) index)) (* 4 4))]
;; (js-debugger)
(.set mem (js/Float32Array. (clj->js [(:x1 sr) (:y1 sr) (:x2 sr) (:y2 sr)])))))
(draw-canvas vbox zoom objects)
(set-objects vbox zoom objects)
(println "set-canvas ok" (.-width canvas) (.-height canvas))))
(defn on-init

View file

@ -28,7 +28,7 @@ var readyPromise = new Promise((resolve, reject) => {
readyPromiseResolve = resolve;
readyPromiseReject = reject;
});
["_alloc_rects","_draw_rect","_draw_shapes","_flush","_init","_main","_make_color","_make_rect","_reset_canvas","_resize_surface","_scale","_translate","getExceptionMessage","incrementExceptionRefcount","decrementExceptionRefcount","_memory","___indirect_function_table","onRuntimeInitialized"].forEach((prop) => {
["_alloc_rects","_draw_rect","_draw_shapes","_flush","_free_rects","_init","_main","_reset_canvas","_resize_surface","_scale","_translate","getExceptionMessage","incrementExceptionRefcount","decrementExceptionRefcount","_memory","___indirect_function_table","onRuntimeInitialized"].forEach((prop) => {
if (!Object.getOwnPropertyDescriptor(readyPromise, prop)) {
Object.defineProperty(readyPromise, prop, {
get: () => abort('You are getting ' + prop + ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js'),
@ -8563,9 +8563,8 @@ var wasmExports = createWasm();
var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors', 0);
var _init = Module['_init'] = createExportWrapper('init', 2);
var _resize_surface = Module['_resize_surface'] = createExportWrapper('resize_surface', 3);
var _make_color = Module['_make_color'] = createExportWrapper('make_color', 4);
var _make_rect = Module['_make_rect'] = createExportWrapper('make_rect', 4);
var _alloc_rects = Module['_alloc_rects'] = createExportWrapper('alloc_rects', 1);
var _free_rects = Module['_free_rects'] = createExportWrapper('free_rects', 2);
var _draw_rect = Module['_draw_rect'] = createExportWrapper('draw_rect', 3);
var _flush = Module['_flush'] = createExportWrapper('flush', 1);
var _translate = Module['_translate'] = createExportWrapper('translate', 3);