mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-17 22:08:39 +00:00
parley: Simplify stroke and brush interface towards the renderer
The renderer needs to provide a PlatformBrush type that encodes if it's a fill or a stroke. In exchange, the stroke style interpretation can be handled in renderer-independent code.
This commit is contained in:
parent
993358dee4
commit
d1ac15ac7e
2 changed files with 101 additions and 98 deletions
|
@ -10,11 +10,9 @@ use std::cell::RefCell;
|
|||
use crate::{
|
||||
graphics::FontRequest,
|
||||
items::TextStrokeStyle,
|
||||
lengths::{
|
||||
LogicalLength, LogicalPoint, LogicalRect, LogicalSize, PhysicalPx, ScaleFactor, SizeLengths,
|
||||
},
|
||||
lengths::{LogicalLength, LogicalPoint, LogicalRect, LogicalSize, ScaleFactor, SizeLengths},
|
||||
textlayout::{TextHorizontalAlignment, TextOverflow, TextVerticalAlignment, TextWrap},
|
||||
Coord, SharedString,
|
||||
SharedString,
|
||||
};
|
||||
use i_slint_common::sharedfontique;
|
||||
|
||||
|
@ -48,14 +46,12 @@ pub trait GlyphRenderer: crate::item_rendering::ItemRenderer {
|
|||
&mut self,
|
||||
font: &parley::Font,
|
||||
font_size: f32,
|
||||
fill_brush: Self::PlatformBrush,
|
||||
stroke_brush: Option<Self::PlatformBrush>,
|
||||
stroke_style: &Option<TextStrokeStyle>,
|
||||
brush: Self::PlatformBrush,
|
||||
y_offset: f32,
|
||||
glyphs_it: &mut dyn Iterator<Item = parley::layout::Glyph>,
|
||||
);
|
||||
|
||||
/// Fills the given rectangle with the specified brush. This is used for drawing selection
|
||||
/// Fills the given rectangle with the specified color. This is used for drawing selection
|
||||
/// rectangles as well as the text cursor.
|
||||
fn fill_rectangle(
|
||||
&mut self,
|
||||
|
@ -63,7 +59,7 @@ pub trait GlyphRenderer: crate::item_rendering::ItemRenderer {
|
|||
physical_y: f32,
|
||||
physical_width: f32,
|
||||
physical_height: f32,
|
||||
brush: Self::PlatformBrush,
|
||||
color: crate::Color,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -296,8 +292,6 @@ impl Layout {
|
|||
&parley::Font,
|
||||
f32,
|
||||
<R as GlyphRenderer>::PlatformBrush,
|
||||
Option<<R as GlyphRenderer>::PlatformBrush>,
|
||||
&Option<TextStrokeStyle>,
|
||||
&mut dyn Iterator<Item = parley::layout::Glyph>,
|
||||
),
|
||||
) {
|
||||
|
@ -335,15 +329,59 @@ impl Layout {
|
|||
None => (default_fill_brush.clone(), &brush.stroke),
|
||||
};
|
||||
|
||||
draw_glyphs(
|
||||
item_renderer,
|
||||
run.font(),
|
||||
run.font_size(),
|
||||
fill_brush,
|
||||
default_stroke_brush.clone(),
|
||||
stroke_style,
|
||||
glyphs_it,
|
||||
);
|
||||
match stroke_style {
|
||||
Some(TextStrokeStyle::Outside) => {
|
||||
let glyphs = glyphs_it.collect::<alloc::vec::Vec<_>>();
|
||||
|
||||
if let Some(stroke_brush) = default_stroke_brush.clone() {
|
||||
draw_glyphs(
|
||||
item_renderer,
|
||||
run.font(),
|
||||
run.font_size(),
|
||||
stroke_brush,
|
||||
&mut glyphs.iter().cloned(),
|
||||
);
|
||||
}
|
||||
|
||||
draw_glyphs(
|
||||
item_renderer,
|
||||
run.font(),
|
||||
run.font_size(),
|
||||
fill_brush,
|
||||
&mut glyphs.into_iter(),
|
||||
);
|
||||
}
|
||||
Some(TextStrokeStyle::Center) => {
|
||||
let glyphs = glyphs_it.collect::<alloc::vec::Vec<_>>();
|
||||
|
||||
draw_glyphs(
|
||||
item_renderer,
|
||||
run.font(),
|
||||
run.font_size(),
|
||||
fill_brush,
|
||||
&mut glyphs.iter().cloned(),
|
||||
);
|
||||
|
||||
if let Some(stroke_brush) = default_stroke_brush.clone() {
|
||||
draw_glyphs(
|
||||
item_renderer,
|
||||
run.font(),
|
||||
run.font_size(),
|
||||
stroke_brush,
|
||||
&mut glyphs.into_iter(),
|
||||
);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
draw_glyphs(
|
||||
item_renderer,
|
||||
run.font(),
|
||||
run.font_size(),
|
||||
fill_brush,
|
||||
glyphs_it,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
parley::PositionedLayoutItem::InlineBox(_inline_box) => {}
|
||||
};
|
||||
|
@ -409,16 +447,8 @@ pub fn draw_text(
|
|||
item_renderer,
|
||||
platform_fill_brush,
|
||||
platform_stroke_brush,
|
||||
&mut |item_renderer, font, font_size, fill_brush, stroke_brush, stroke_style, glyphs_it| {
|
||||
item_renderer.draw_glyph_run(
|
||||
font,
|
||||
font_size,
|
||||
fill_brush,
|
||||
stroke_brush,
|
||||
stroke_style,
|
||||
layout.y_offset,
|
||||
glyphs_it,
|
||||
);
|
||||
&mut |item_renderer, font, font_size, brush, glyphs_it| {
|
||||
item_renderer.draw_glyph_run(font, font_size, brush, layout.y_offset, glyphs_it);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -487,35 +517,21 @@ pub fn draw_text_input(
|
|||
),
|
||||
);
|
||||
selection.geometry_with(&layout.inner, |rect, _| {
|
||||
if let Some(selection_brush) = item_renderer.platform_text_fill_brush(
|
||||
text_input.selection_background_color().into(),
|
||||
euclid::size2::<Coord, PhysicalPx>(rect.width() as _, rect.height() as _)
|
||||
/ scale_factor,
|
||||
) {
|
||||
item_renderer.fill_rectangle(
|
||||
rect.min_x() as _,
|
||||
rect.min_y() as f32 + layout.y_offset,
|
||||
rect.width() as _,
|
||||
rect.height() as _,
|
||||
selection_brush,
|
||||
);
|
||||
}
|
||||
item_renderer.fill_rectangle(
|
||||
rect.min_x() as _,
|
||||
rect.min_y() as f32 + layout.y_offset,
|
||||
rect.width() as _,
|
||||
rect.height() as _,
|
||||
text_input.selection_background_color(),
|
||||
);
|
||||
});
|
||||
|
||||
layout.draw(
|
||||
item_renderer,
|
||||
platform_fill_brush,
|
||||
None,
|
||||
&mut |item_renderer, font, font_size, fill_brush, stroke_brush, stroke_style, glyphs_it| {
|
||||
item_renderer.draw_glyph_run(
|
||||
font,
|
||||
font_size,
|
||||
fill_brush,
|
||||
stroke_brush,
|
||||
stroke_style,
|
||||
layout.y_offset,
|
||||
glyphs_it,
|
||||
);
|
||||
&mut |item_renderer, font, font_size, brush, glyphs_it| {
|
||||
item_renderer.draw_glyph_run(font, font_size, brush, layout.y_offset, glyphs_it);
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -528,19 +544,13 @@ pub fn draw_text_input(
|
|||
let rect =
|
||||
cursor.geometry(&layout.inner, (text_input.text_cursor_width() * scale_factor).get());
|
||||
|
||||
if let Some(cursor_brush) = item_renderer.platform_text_fill_brush(
|
||||
visual_representation.cursor_color.into(),
|
||||
euclid::size2::<Coord, PhysicalPx>(rect.width() as _, rect.height() as _)
|
||||
/ scale_factor,
|
||||
) {
|
||||
item_renderer.fill_rectangle(
|
||||
rect.min_x() as _,
|
||||
rect.min_y() as f32 + layout.y_offset,
|
||||
rect.width() as _,
|
||||
rect.height() as _,
|
||||
cursor_brush,
|
||||
);
|
||||
}
|
||||
item_renderer.fill_rectangle(
|
||||
rect.min_x() as _,
|
||||
rect.min_y() as f32 + layout.y_offset,
|
||||
rect.width() as _,
|
||||
rect.height() as _,
|
||||
visual_representation.cursor_color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ use i_slint_core::item_rendering::{
|
|||
};
|
||||
use i_slint_core::items::{
|
||||
self, Clip, FillRule, ImageRendering, ImageTiling, ItemRc, Layer, Opacity, RenderingResult,
|
||||
TextStrokeStyle,
|
||||
};
|
||||
use i_slint_core::lengths::{
|
||||
LogicalBorderRadius, LogicalLength, LogicalPoint, LogicalRect, LogicalSize, LogicalVector,
|
||||
|
@ -909,8 +908,14 @@ impl<'a, R: femtovg::Renderer + TextureImporter> ItemRenderer for GLItemRenderer
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum GlyphBrush {
|
||||
Fill(femtovg::Paint),
|
||||
Stroke(femtovg::Paint),
|
||||
}
|
||||
|
||||
impl<'a, R: femtovg::Renderer + TextureImporter> GlyphRenderer for GLItemRenderer<'a, R> {
|
||||
type PlatformBrush = femtovg::Paint;
|
||||
type PlatformBrush = GlyphBrush;
|
||||
|
||||
fn platform_text_fill_brush(
|
||||
&mut self,
|
||||
|
@ -918,7 +923,7 @@ impl<'a, R: femtovg::Renderer + TextureImporter> GlyphRenderer for GLItemRendere
|
|||
size: LogicalSize,
|
||||
) -> Option<Self::PlatformBrush> {
|
||||
let text_path = rect_to_path((size * self.scale_factor).into());
|
||||
self.brush_to_paint(brush, &text_path)
|
||||
self.brush_to_paint(brush, &text_path).map(GlyphBrush::Fill)
|
||||
}
|
||||
|
||||
fn platform_brush_for_color(
|
||||
|
@ -928,7 +933,7 @@ impl<'a, R: femtovg::Renderer + TextureImporter> GlyphRenderer for GLItemRendere
|
|||
if color.alpha() == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(femtovg::Paint::color(to_femtovg_color(&color)))
|
||||
Some(GlyphBrush::Fill(femtovg::Paint::color(to_femtovg_color(&color))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -945,7 +950,7 @@ impl<'a, R: femtovg::Renderer + TextureImporter> GlyphRenderer for GLItemRendere
|
|||
None
|
||||
} else {
|
||||
paint.set_line_width(physical_stroke_width);
|
||||
Some(paint)
|
||||
Some(GlyphBrush::Stroke(paint))
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
|
@ -956,9 +961,7 @@ impl<'a, R: femtovg::Renderer + TextureImporter> GlyphRenderer for GLItemRendere
|
|||
&mut self,
|
||||
font: &parley::Font,
|
||||
font_size: f32,
|
||||
mut fill_brush: Self::PlatformBrush,
|
||||
mut stroke_brush: Option<Self::PlatformBrush>,
|
||||
stroke_style: &Option<TextStrokeStyle>,
|
||||
mut brush: Self::PlatformBrush,
|
||||
y_offset: f32,
|
||||
glyphs_it: &mut dyn Iterator<Item = parley::layout::Glyph>,
|
||||
) {
|
||||
|
@ -970,32 +973,16 @@ impl<'a, R: femtovg::Renderer + TextureImporter> GlyphRenderer for GLItemRendere
|
|||
glyph_id: glyph.id,
|
||||
});
|
||||
|
||||
fill_brush.set_font_size(font_size);
|
||||
if let Some(stroke_brush) = stroke_brush.as_mut() {
|
||||
stroke_brush.set_font_size(font_size);
|
||||
}
|
||||
|
||||
let mut canvas = self.canvas.borrow_mut();
|
||||
|
||||
match stroke_style {
|
||||
Some(i_slint_core::items::TextStrokeStyle::Outside) => {
|
||||
let glyphs = glyphs_it.collect::<Vec<_>>();
|
||||
|
||||
if let Some(stroke_brush) = stroke_brush.as_ref() {
|
||||
canvas.stroke_glyph_run(font_id, glyphs.clone(), &stroke_brush).unwrap();
|
||||
}
|
||||
canvas.fill_glyph_run(font_id, glyphs, &fill_brush).unwrap();
|
||||
match &mut brush {
|
||||
GlyphBrush::Fill(paint) => {
|
||||
paint.set_font_size(font_size);
|
||||
canvas.fill_glyph_run(font_id, glyphs_it, &paint).unwrap();
|
||||
}
|
||||
Some(i_slint_core::items::TextStrokeStyle::Center) => {
|
||||
let glyphs = glyphs_it.collect::<Vec<_>>();
|
||||
|
||||
canvas.fill_glyph_run(font_id, glyphs.clone(), &fill_brush).unwrap();
|
||||
if let Some(stroke_brush) = stroke_brush.as_ref() {
|
||||
canvas.stroke_glyph_run(font_id, glyphs.clone(), &stroke_brush).unwrap();
|
||||
}
|
||||
}
|
||||
None => {
|
||||
canvas.fill_glyph_run(font_id, glyphs_it, &fill_brush).unwrap();
|
||||
GlyphBrush::Stroke(paint) => {
|
||||
paint.set_font_size(font_size);
|
||||
canvas.stroke_glyph_run(font_id, glyphs_it, &paint).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1006,8 +993,14 @@ impl<'a, R: femtovg::Renderer + TextureImporter> GlyphRenderer for GLItemRendere
|
|||
physical_y: f32,
|
||||
physical_width: f32,
|
||||
physical_height: f32,
|
||||
paint: Self::PlatformBrush,
|
||||
color: Color,
|
||||
) {
|
||||
if color.alpha() == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let paint = femtovg::Paint::color(to_femtovg_color(&color));
|
||||
|
||||
let mut path = femtovg::Path::new();
|
||||
path.rect(physical_x, physical_y, physical_width, physical_height);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue