From b157648ab2fac94e83d162edb29b09bbac18a3a5 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 5 Jan 2021 13:02:52 +0100 Subject: [PATCH] More work towards getting native widget with the femtovg backend --- sixtyfps_runtime/corelib/items.rs | 2 +- .../rendering_backends/gl/Cargo.toml | 2 ++ sixtyfps_runtime/rendering_backends/gl/lib.rs | 19 ++++++++++-- .../rendering_backends/qt/widgets.rs | 31 ++++++++++++------- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/sixtyfps_runtime/corelib/items.rs b/sixtyfps_runtime/corelib/items.rs index 656a489ab..4ce966577 100644 --- a/sixtyfps_runtime/corelib/items.rs +++ b/sixtyfps_runtime/corelib/items.rs @@ -48,7 +48,7 @@ pub use self::image::*; pub trait RawRenderer { /// Draw a pixmap in position indicated by the `pos`. /// The data must be argb pixels of size width x height. - fn draw_pixmap(&mut self, pos: Point, width: u32, height: u32, data: &[u32]); + fn draw_pixmap(&mut self, pos: Point, width: u32, height: u32, data: &[u8]); /// Returns the scale factor fn scale_factor(&self) -> f32; diff --git a/sixtyfps_runtime/rendering_backends/gl/Cargo.toml b/sixtyfps_runtime/rendering_backends/gl/Cargo.toml index 552fc14f2..d85f4764d 100644 --- a/sixtyfps_runtime/rendering_backends/gl/Cargo.toml +++ b/sixtyfps_runtime/rendering_backends/gl/Cargo.toml @@ -21,6 +21,8 @@ default = ["x11"] sixtyfps-corelib = { version = "=0.0.4", path = "../../corelib", features = ["femtovg_backend"] } lyon = { version = "0.16" } image = { version = "0.23.12", default-features = false } +rgb = "0.8" +imgref = "1.6.1" cgmath = "0.17.0" vtable = { version = "0.1", path = "../../../helper_crates/vtable" } pathfinder_geometry = "0.5.1" diff --git a/sixtyfps_runtime/rendering_backends/gl/lib.rs b/sixtyfps_runtime/rendering_backends/gl/lib.rs index 22f9fe5dc..9afe93347 100644 --- a/sixtyfps_runtime/rendering_backends/gl/lib.rs +++ b/sixtyfps_runtime/rendering_backends/gl/lib.rs @@ -256,8 +256,23 @@ fn rect_to_path(r: Rect) -> femtovg::Path { } impl sixtyfps_corelib::items::RawRenderer for GLItemRenderer { - fn draw_pixmap(&mut self, _: Point, _: u32, _: u32, _: &[u32]) { - todo!() + fn draw_pixmap(&mut self, pos: Point, width: u32, height: u32, data: &[u8]) { + use rgb::FromSlice; + let mut canvas = self.canvas.borrow_mut(); + let img = imgref::Img::new(data.as_rgba(), width as usize, height as usize); + let image_id = match canvas.create_image(img, femtovg::ImageFlags::empty()) { + Ok(x) => x, + Err(_) => return, + }; + let info = canvas.image_info(image_id).unwrap(); + + let (image_width, image_height) = (info.width() as f32, info.height() as f32); + let (source_width, source_height) = (image_width, image_height); + let fill_paint = + femtovg::Paint::image(image_id, 0., 0., source_width, source_height, 0.0, 1.0); + let mut path = femtovg::Path::new(); + path.rect(pos.x, pos.y, image_width, image_height); + canvas.fill_path(&mut path, fill_paint); } fn scale_factor(&self) -> f32 { diff --git a/sixtyfps_runtime/rendering_backends/qt/widgets.rs b/sixtyfps_runtime/rendering_backends/qt/widgets.rs index ffda2d43e..582aeeb83 100644 --- a/sixtyfps_runtime/rendering_backends/qt/widgets.rs +++ b/sixtyfps_runtime/rendering_backends/qt/widgets.rs @@ -28,7 +28,7 @@ use const_field_offset::FieldOffsets; use core::pin::Pin; use cpp::cpp; use sixtyfps_corelib::eventloop::ComponentWindow; -use sixtyfps_corelib::graphics::{Point, Rect, Resource}; +use sixtyfps_corelib::graphics::{Point, Rect}; use sixtyfps_corelib::input::{ FocusEvent, InputEventResult, KeyEvent, KeyEventResult, MouseEvent, MouseEventType, }; @@ -57,16 +57,25 @@ macro_rules! get_size { }}; } +/// Helper macro to get the possition of this item, given an offset Point, +macro_rules! get_pos { + ($self:ident + $offset:expr) => {{ + let x = Self::FIELD_OFFSETS.x.apply_pin($self).get(); + let y = Self::FIELD_OFFSETS.y.apply_pin($self).get(); + Point::new(x, y) + $offset.to_vector() + }}; +} + struct QImageWrapArray { /// The image reference the array, so the array must outlive the image without being detached or accessed img: qttypes::QImage, - array: SharedVector, + array: SharedVector, } impl QImageWrapArray { pub fn new(size: qttypes::QSize, dpr: f32) -> Self { let mut array = SharedVector::default(); - array.resize((size.width * size.height) as usize, 0u32); + array.resize((size.width * size.height * 4) as usize, 0); let array_ptr = array.as_slice_mut().as_mut_ptr(); let img = cpp!(unsafe [size as "QSize", array_ptr as "uchar*", dpr as "float"] -> qttypes::QImage as "QImage" { QImage img(array_ptr, size.width(), size.height(), size.width() * 4, QImage::Format_ARGB32_Premultiplied); @@ -220,7 +229,7 @@ impl Item for NativeButton { } qApp->style()->drawControl(QStyle::CE_PushButton, &option, &p, nullptr); }); - imgarray.draw(pos, *backend); + imgarray.draw(get_pos!(self + pos), *backend); } } @@ -335,7 +344,7 @@ impl Item for NativeCheckBox { } qApp->style()->drawControl(QStyle::CE_CheckBox, &option, &p, nullptr); }); - imgarray.draw(pos, *backend); + imgarray.draw(get_pos!(self + pos), *backend); } } @@ -547,7 +556,7 @@ impl Item for NativeSpinBox { p.setPen(option.palette.color(QPalette::Text)); p.drawText(text_rect, QString::number(value)); }); - imgarray.draw(pos, *backend); + imgarray.draw(get_pos!(self + pos), *backend); } } @@ -757,7 +766,7 @@ impl Item for NativeSlider { auto style = qApp->style(); style->drawComplexControl(QStyle::CC_Slider, &option, &p, nullptr); }); - imgarray.draw(pos, *backend); + imgarray.draw(get_pos!(self + pos), *backend); } } @@ -956,7 +965,7 @@ impl Item for NativeGroupBox { QStyle::SH_GroupBox_TextLabelColor, &option)); qApp->style()->drawComplexControl(QStyle::CC_GroupBox, &option, &p, nullptr); }); - imgarray.draw(pos, *backend); + imgarray.draw(get_pos!(self + pos), *backend); } } @@ -1102,7 +1111,7 @@ impl Item for NativeLineEdit { } qApp->style()->drawPrimitive(QStyle::PE_PanelLineEdit, &option, &p, nullptr); }); - imgarray.draw(pos, *backend); + imgarray.draw(get_pos!(self + pos), *backend); } } @@ -1478,7 +1487,7 @@ impl Item for NativeScrollView { data.pressed == 1, ); - imgarray.draw(pos, *backend); + imgarray.draw(get_pos!(self + pos), *backend); } } @@ -1600,7 +1609,7 @@ impl Item for NativeStandardListViewItem { qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, &p, nullptr); qApp->style()->drawControl(QStyle::CE_ItemViewItem, &option, &p, nullptr); }); - imgarray.draw(pos, *backend); + imgarray.draw(get_pos!(self + pos), *backend); } }