More work towards getting native widget with the femtovg backend

This commit is contained in:
Olivier Goffart 2021-01-05 13:02:52 +01:00 committed by Simon Hausmann
parent 7643174f28
commit b157648ab2
4 changed files with 40 additions and 14 deletions

View file

@ -48,7 +48,7 @@ pub use self::image::*;
pub trait RawRenderer { pub trait RawRenderer {
/// Draw a pixmap in position indicated by the `pos`. /// Draw a pixmap in position indicated by the `pos`.
/// The data must be argb pixels of size width x height. /// 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 /// Returns the scale factor
fn scale_factor(&self) -> f32; fn scale_factor(&self) -> f32;

View file

@ -21,6 +21,8 @@ default = ["x11"]
sixtyfps-corelib = { version = "=0.0.4", path = "../../corelib", features = ["femtovg_backend"] } sixtyfps-corelib = { version = "=0.0.4", path = "../../corelib", features = ["femtovg_backend"] }
lyon = { version = "0.16" } lyon = { version = "0.16" }
image = { version = "0.23.12", default-features = false } image = { version = "0.23.12", default-features = false }
rgb = "0.8"
imgref = "1.6.1"
cgmath = "0.17.0" cgmath = "0.17.0"
vtable = { version = "0.1", path = "../../../helper_crates/vtable" } vtable = { version = "0.1", path = "../../../helper_crates/vtable" }
pathfinder_geometry = "0.5.1" pathfinder_geometry = "0.5.1"

View file

@ -256,8 +256,23 @@ fn rect_to_path(r: Rect) -> femtovg::Path {
} }
impl sixtyfps_corelib::items::RawRenderer for GLItemRenderer { impl sixtyfps_corelib::items::RawRenderer for GLItemRenderer {
fn draw_pixmap(&mut self, _: Point, _: u32, _: u32, _: &[u32]) { fn draw_pixmap(&mut self, pos: Point, width: u32, height: u32, data: &[u8]) {
todo!() 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 { fn scale_factor(&self) -> f32 {

View file

@ -28,7 +28,7 @@ use const_field_offset::FieldOffsets;
use core::pin::Pin; use core::pin::Pin;
use cpp::cpp; use cpp::cpp;
use sixtyfps_corelib::eventloop::ComponentWindow; use sixtyfps_corelib::eventloop::ComponentWindow;
use sixtyfps_corelib::graphics::{Point, Rect, Resource}; use sixtyfps_corelib::graphics::{Point, Rect};
use sixtyfps_corelib::input::{ use sixtyfps_corelib::input::{
FocusEvent, InputEventResult, KeyEvent, KeyEventResult, MouseEvent, MouseEventType, 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 { struct QImageWrapArray {
/// The image reference the array, so the array must outlive the image without being detached or accessed /// The image reference the array, so the array must outlive the image without being detached or accessed
img: qttypes::QImage, img: qttypes::QImage,
array: SharedVector<u32>, array: SharedVector<u8>,
} }
impl QImageWrapArray { impl QImageWrapArray {
pub fn new(size: qttypes::QSize, dpr: f32) -> Self { pub fn new(size: qttypes::QSize, dpr: f32) -> Self {
let mut array = SharedVector::default(); 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 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" { 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); 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); 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); 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.setPen(option.palette.color(QPalette::Text));
p.drawText(text_rect, QString::number(value)); 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(); auto style = qApp->style();
style->drawComplexControl(QStyle::CC_Slider, &option, &p, nullptr); 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)); QStyle::SH_GroupBox_TextLabelColor, &option));
qApp->style()->drawComplexControl(QStyle::CC_GroupBox, &option, &p, nullptr); 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); 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, 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()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, &p, nullptr);
qApp->style()->drawControl(QStyle::CE_ItemViewItem, &option, &p, nullptr); qApp->style()->drawControl(QStyle::CE_ItemViewItem, &option, &p, nullptr);
}); });
imgarray.draw(pos, *backend); imgarray.draw(get_pos!(self + pos), *backend);
} }
} }