mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Fix path fitting
Include the stroke width in the boundaries when fitting a path into the size of a `Path` element.
This commit is contained in:
parent
fd3c8bf9fa
commit
d92c8cab23
3 changed files with 28 additions and 4 deletions
|
@ -25,6 +25,7 @@ When adding an item or a property, it needs to be kept in sync with different pl
|
||||||
#![allow(missing_docs)] // because documenting each property of items is redundent
|
#![allow(missing_docs)] // because documenting each property of items is redundent
|
||||||
|
|
||||||
use crate::component::ComponentVTable;
|
use crate::component::ComponentVTable;
|
||||||
|
use crate::graphics::PathDataIterator;
|
||||||
use crate::graphics::{Brush, Color, PathData, Point, Rect, Size};
|
use crate::graphics::{Brush, Color, PathData, Point, Rect, Size};
|
||||||
use crate::input::{
|
use crate::input::{
|
||||||
FocusEvent, InputEventResult, KeyEvent, KeyEventResult, KeyEventType, MouseEvent,
|
FocusEvent, InputEventResult, KeyEvent, KeyEventResult, KeyEventType, MouseEvent,
|
||||||
|
@ -600,6 +601,22 @@ impl Item for Path {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Path {
|
||||||
|
/// Returns an iterator of the events of the path and an offset, so that the
|
||||||
|
/// shape fits into the width/height of the path while respecting the stroke
|
||||||
|
/// width.
|
||||||
|
pub fn fitted_path_events(
|
||||||
|
self: Pin<&Self>,
|
||||||
|
) -> (euclid::default::Vector2D<f32>, PathDataIterator) {
|
||||||
|
let stroke_width = self.stroke_width();
|
||||||
|
let bounds_width = (self.width() - stroke_width).max(0.);
|
||||||
|
let bounds_height = (self.height() - stroke_width).max(0.);
|
||||||
|
let offset = euclid::default::Vector2D::new(stroke_width / 2., stroke_width / 2.);
|
||||||
|
let event_iterator = self.elements().iter_fitted(bounds_width, bounds_height);
|
||||||
|
(offset, event_iterator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ItemConsts for Path {
|
impl ItemConsts for Path {
|
||||||
const cached_rendering_data_offset: const_field_offset::FieldOffset<Path, CachedRenderingData> =
|
const cached_rendering_data_offset: const_field_offset::FieldOffset<Path, CachedRenderingData> =
|
||||||
Path::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection();
|
Path::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection();
|
||||||
|
|
|
@ -954,8 +954,11 @@ impl ItemRenderer for GLItemRenderer {
|
||||||
if matches!(elements, sixtyfps_corelib::PathData::None) {
|
if matches!(elements, sixtyfps_corelib::PathData::None) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (offset, path_events) = path.fitted_path_events();
|
||||||
|
|
||||||
let mut fpath = femtovg::Path::new();
|
let mut fpath = femtovg::Path::new();
|
||||||
for x in elements.iter_fitted(path.width(), path.height()).iter() {
|
for x in path_events.iter() {
|
||||||
match x {
|
match x {
|
||||||
lyon_path::Event::Begin { at } => {
|
lyon_path::Event::Begin { at } => {
|
||||||
fpath.move_to(at.x, at.y);
|
fpath.move_to(at.x, at.y);
|
||||||
|
@ -983,7 +986,7 @@ impl ItemRenderer for GLItemRenderer {
|
||||||
border_paint.set_line_width(path.stroke_width());
|
border_paint.set_line_width(path.stroke_width());
|
||||||
|
|
||||||
self.shared_data.canvas.borrow_mut().save_with(|canvas| {
|
self.shared_data.canvas.borrow_mut().save_with(|canvas| {
|
||||||
canvas.translate(pos.x + path.x(), pos.y + path.y());
|
canvas.translate(pos.x + path.x() + offset.x, pos.y + path.y() + offset.y);
|
||||||
canvas.fill_path(&mut fpath, fill_paint);
|
canvas.fill_path(&mut fpath, fill_paint);
|
||||||
canvas.stroke_path(&mut fpath, border_paint);
|
canvas.stroke_path(&mut fpath, border_paint);
|
||||||
})
|
})
|
||||||
|
|
|
@ -372,12 +372,16 @@ impl ItemRenderer for QtItemRenderer<'_> {
|
||||||
}
|
}
|
||||||
// FIXME: handle width/height
|
// FIXME: handle width/height
|
||||||
//let rect: qttypes::QRectF = get_geometry!(pos, items::Path, path);
|
//let rect: qttypes::QRectF = get_geometry!(pos, items::Path, path);
|
||||||
let pos = qttypes::QPoint { x: (pos.x + path.x()) as _, y: (pos.y + path.y()) as _ };
|
|
||||||
let fill_brush: qttypes::QBrush = path.fill().into();
|
let fill_brush: qttypes::QBrush = path.fill().into();
|
||||||
let stroke_brush: qttypes::QBrush = path.stroke().into();
|
let stroke_brush: qttypes::QBrush = path.stroke().into();
|
||||||
let stroke_width: f32 = path.stroke_width();
|
let stroke_width: f32 = path.stroke_width();
|
||||||
|
let (offset, path_events) = path.fitted_path_events();
|
||||||
|
let pos = qttypes::QPoint {
|
||||||
|
x: (pos.x + path.x() + offset.x) as _,
|
||||||
|
y: (pos.y + path.y() + offset.y) as _,
|
||||||
|
};
|
||||||
let mut painter_path = QPainterPath::default();
|
let mut painter_path = QPainterPath::default();
|
||||||
for x in elements.iter_fitted(path.width(), path.height()).iter() {
|
for x in path_events.iter() {
|
||||||
impl From<Point> for qttypes::QPointF {
|
impl From<Point> for qttypes::QPointF {
|
||||||
fn from(p: Point) -> Self {
|
fn from(p: Point) -> Self {
|
||||||
qttypes::QPointF { x: p.x as _, y: p.y as _ }
|
qttypes::QPointF { x: p.x as _, y: p.y as _ }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue