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
|
||||
|
||||
use crate::component::ComponentVTable;
|
||||
use crate::graphics::PathDataIterator;
|
||||
use crate::graphics::{Brush, Color, PathData, Point, Rect, Size};
|
||||
use crate::input::{
|
||||
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 {
|
||||
const cached_rendering_data_offset: const_field_offset::FieldOffset<Path, CachedRenderingData> =
|
||||
Path::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection();
|
||||
|
|
|
@ -954,8 +954,11 @@ impl ItemRenderer for GLItemRenderer {
|
|||
if matches!(elements, sixtyfps_corelib::PathData::None) {
|
||||
return;
|
||||
}
|
||||
|
||||
let (offset, path_events) = path.fitted_path_events();
|
||||
|
||||
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 {
|
||||
lyon_path::Event::Begin { at } => {
|
||||
fpath.move_to(at.x, at.y);
|
||||
|
@ -983,7 +986,7 @@ impl ItemRenderer for GLItemRenderer {
|
|||
border_paint.set_line_width(path.stroke_width());
|
||||
|
||||
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.stroke_path(&mut fpath, border_paint);
|
||||
})
|
||||
|
|
|
@ -372,12 +372,16 @@ impl ItemRenderer for QtItemRenderer<'_> {
|
|||
}
|
||||
// FIXME: handle width/height
|
||||
//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 stroke_brush: qttypes::QBrush = path.stroke().into();
|
||||
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();
|
||||
for x in elements.iter_fitted(path.width(), path.height()).iter() {
|
||||
for x in path_events.iter() {
|
||||
impl From<Point> for qttypes::QPointF {
|
||||
fn from(p: Point) -> Self {
|
||||
qttypes::QPointF { x: p.x as _, y: p.y as _ }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue