mirror of
https://github.com/slint-ui/slint.git
synced 2025-12-23 09:19:32 +00:00
Add stroke-line-join for Path (#9912)
* Add `stroke-line-join` for `Path` * Add `LineJoin` enum * Add `stroke-line-join` property for `Path` * Set line_join in Skia and FemtoVG renders * Set pen_join_style in Qt backend * Add example test case * Docs: Add `stroke-line-join` property for `Path`
This commit is contained in:
parent
0bdb99d2c4
commit
bbd5d8554b
8 changed files with 95 additions and 4 deletions
|
|
@ -47,6 +47,11 @@ The width of the outline.
|
|||
The appearance of the ends of the path's outline.
|
||||
</SlintProperty>
|
||||
|
||||
### stroke-line-join
|
||||
<SlintProperty propName="stroke-line-join" typeName="enum" enumName="LineJoin" defaultValue='miter'>
|
||||
The appearance of the joins between segments of stroked paths.
|
||||
</SlintProperty>
|
||||
|
||||
### width
|
||||
<SlintProperty propName="width" typeName="length">
|
||||
If non-zero, the path will be scaled to fit into the specified width.
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ use i_slint_core::item_rendering::{
|
|||
use i_slint_core::item_tree::ParentItemTraversalMode;
|
||||
use i_slint_core::item_tree::{ItemTreeRc, ItemTreeRef, ItemTreeWeak};
|
||||
use i_slint_core::items::{
|
||||
self, ColorScheme, FillRule, ImageRendering, ItemRc, ItemRef, Layer, LineCap, MouseCursor,
|
||||
Opacity, PointerEventButton, RenderingResult, TextWrap,
|
||||
self, ColorScheme, FillRule, ImageRendering, ItemRc, ItemRef, Layer, LineCap, LineJoin,
|
||||
MouseCursor, Opacity, PointerEventButton, RenderingResult, TextWrap,
|
||||
};
|
||||
use i_slint_core::layout::Orientation;
|
||||
use i_slint_core::lengths::{
|
||||
|
|
@ -716,6 +716,12 @@ impl ItemRenderer for QtItemRenderer<'_> {
|
|||
LineCap::Round => 0x20,
|
||||
LineCap::Square => 0x10,
|
||||
};
|
||||
let stroke_pen_join_style: i32 = match path.stroke_line_join() {
|
||||
LineJoin::Miter => 0x00,
|
||||
LineJoin::Round => 0x80,
|
||||
LineJoin::Bevel => 0x40,
|
||||
};
|
||||
|
||||
let pos = qttypes::QPoint { x: offset.x as _, y: offset.y as _ };
|
||||
let mut painter_path = QPainterPath::default();
|
||||
|
||||
|
|
@ -762,11 +768,12 @@ impl ItemRenderer for QtItemRenderer<'_> {
|
|||
stroke_brush as "QBrush",
|
||||
stroke_width as "float",
|
||||
stroke_pen_cap_style as "int",
|
||||
stroke_pen_join_style as "int",
|
||||
anti_alias as "bool"] {
|
||||
(*painter)->save();
|
||||
auto cleanup = qScopeGuard([&] { (*painter)->restore(); });
|
||||
(*painter)->translate(pos);
|
||||
(*painter)->setPen(stroke_width > 0 ? QPen(stroke_brush, stroke_width, Qt::SolidLine, Qt::PenCapStyle(stroke_pen_cap_style)) : Qt::NoPen);
|
||||
(*painter)->setPen(stroke_width > 0 ? QPen(stroke_brush, stroke_width, Qt::SolidLine, Qt::PenCapStyle(stroke_pen_cap_style), Qt::PenJoinStyle(stroke_pen_join_style)) : Qt::NoPen);
|
||||
(*painter)->setBrush(fill_brush);
|
||||
(*painter)->setRenderHint(QPainter::Antialiasing, anti_alias);
|
||||
(*painter)->drawPath(painter_path);
|
||||
|
|
|
|||
|
|
@ -480,6 +480,16 @@ macro_rules! for_each_enums {
|
|||
Square,
|
||||
}
|
||||
|
||||
/// This enum describes the appearance of the joins between segments of stroked paths.
|
||||
enum LineJoin {
|
||||
/// The stroke joins with a sharp corner or a clipped corner, depending on the miter limit.
|
||||
Miter,
|
||||
/// The stroke joins with a smooth, rounded corner.
|
||||
Round,
|
||||
/// The stroke joins with a beveled (flattened) corner.
|
||||
Bevel,
|
||||
}
|
||||
|
||||
/// This enum describes the detected operating system types.
|
||||
#[non_exhaustive]
|
||||
enum OperatingSystemType {
|
||||
|
|
|
|||
|
|
@ -501,6 +501,7 @@ export component Path {
|
|||
in property <brush> stroke;
|
||||
in property <length> stroke-width;
|
||||
in property <LineCap> stroke-line-cap;
|
||||
in property <LineJoin> stroke-line-join;
|
||||
in property <string> commands; // 'fake' hardcoded in typeregister.rs
|
||||
in property <float> viewbox-x;
|
||||
in property <float> viewbox-y;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ When adding an item or a property, it needs to be kept in sync with different pl
|
|||
Lookup the [`crate::items`] module documentation.
|
||||
*/
|
||||
|
||||
use super::{FillRule, Item, ItemConsts, ItemRc, ItemRendererRef, LineCap, RenderingResult};
|
||||
use super::{
|
||||
FillRule, Item, ItemConsts, ItemRc, ItemRendererRef, LineCap, LineJoin, RenderingResult,
|
||||
};
|
||||
use crate::graphics::{Brush, PathData, PathDataIterator};
|
||||
use crate::input::{
|
||||
FocusEvent, FocusEventResult, InputEventFilterResult, InputEventResult, KeyEvent,
|
||||
|
|
@ -41,6 +43,7 @@ pub struct Path {
|
|||
pub stroke: Property<Brush>,
|
||||
pub stroke_width: Property<LogicalLength>,
|
||||
pub stroke_line_cap: Property<LineCap>,
|
||||
pub stroke_line_join: Property<LineJoin>,
|
||||
pub viewbox_x: Property<f32>,
|
||||
pub viewbox_y: Property<f32>,
|
||||
pub viewbox_width: Property<f32>,
|
||||
|
|
|
|||
|
|
@ -461,6 +461,11 @@ impl<'a, R: femtovg::Renderer + TextureImporter> ItemRenderer for GLItemRenderer
|
|||
items::LineCap::Round => femtovg::LineCap::Round,
|
||||
items::LineCap::Square => femtovg::LineCap::Square,
|
||||
});
|
||||
paint.set_line_join(match path.stroke_line_join() {
|
||||
items::LineJoin::Miter => femtovg::LineJoin::Miter,
|
||||
items::LineJoin::Round => femtovg::LineJoin::Round,
|
||||
items::LineJoin::Bevel => femtovg::LineJoin::Bevel,
|
||||
});
|
||||
paint.set_anti_alias(anti_alias);
|
||||
paint
|
||||
});
|
||||
|
|
|
|||
|
|
@ -656,6 +656,11 @@ impl ItemRenderer for SkiaItemRenderer<'_> {
|
|||
i_slint_core::items::LineCap::Round => skia_safe::PaintCap::Round,
|
||||
i_slint_core::items::LineCap::Square => skia_safe::PaintCap::Square,
|
||||
});
|
||||
border_paint.set_stroke_join(match path.stroke_line_join() {
|
||||
i_slint_core::items::LineJoin::Miter => skia_safe::PaintJoin::Miter,
|
||||
i_slint_core::items::LineJoin::Round => skia_safe::PaintJoin::Round,
|
||||
i_slint_core::items::LineJoin::Bevel => skia_safe::PaintJoin::Bevel,
|
||||
});
|
||||
border_paint.set_stroke(true);
|
||||
self.canvas.draw_path(&skpath, &border_paint);
|
||||
}
|
||||
|
|
|
|||
55
tests/cases/examples/path_line_join.slint
Normal file
55
tests/cases/examples/path_line_join.slint
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
PathLineJoin := Window {
|
||||
GridLayout {
|
||||
Row {
|
||||
Text {
|
||||
text: "The path to the right should have rounded corners (line-join: round)";
|
||||
}
|
||||
Path {
|
||||
commands: "M10.5 15.5 9 17l-1.5-1.5";
|
||||
fill: transparent;
|
||||
stroke: white;
|
||||
stroke-width: 10px;
|
||||
stroke-line-join: round;
|
||||
}
|
||||
}
|
||||
Row {
|
||||
Text {
|
||||
text: "The path to the right should have sharp pointed corners (line-join: miter)";
|
||||
}
|
||||
Path {
|
||||
commands: "M10.5 15.5 9 17l-1.5-1.5";
|
||||
fill: transparent;
|
||||
stroke: white;
|
||||
stroke-width: 10px;
|
||||
stroke-line-join: miter;
|
||||
}
|
||||
}
|
||||
Row {
|
||||
Text {
|
||||
text: "The path to the right should have beveled/flat corners (line-join: bevel)";
|
||||
}
|
||||
Path {
|
||||
commands: "M10.5 15.5 9 17l-1.5-1.5";
|
||||
fill: transparent;
|
||||
stroke: white;
|
||||
stroke-width: 10px;
|
||||
stroke-line-join: bevel;
|
||||
}
|
||||
}
|
||||
Row {
|
||||
Text {
|
||||
text: "Zigzag pattern with round joins - should show smooth rounded corners";
|
||||
}
|
||||
Path {
|
||||
commands: "m15 17-1.5-1.5L12 17l-1.5-1.5L9 17l-1.5-1.5";
|
||||
fill: transparent;
|
||||
stroke: white;
|
||||
stroke-width: 10px;
|
||||
stroke-line-join: round;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue