mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 11:36:11 +02:00
🔧 Enable back clippy rules (#6492)
* 🔧 Fix lint script (rust) * 🔧 Temporarily add clippy rules to ignore so lint script passes * 💄 Fix clippy rule crate_in_macro_def * 💄 Fix clippy rule redundant-static-lifetimes * 💄 Fix clippy rule unnecessary_cast * 💄 Fix clippy rule nonminimal_bool * 💄 Fix clippy rule redundant_pattern_matching * 💄 Fix clippy rule assign_op_pattern * 💄 Fix clippy rule needless_lifetimes * 💄 Fix clippy rule for_kv_map * 💄 Fix clippy rule ptr_arg * 💄 Fix clippy rule match_like_matches_macro * 💄 Fix clippy rule macro_metavars_in_unsafe * 💄 Fix clippy rule map_clone * 💄 Fix clippy rule wrong_self_convention * 💄 Fix clippy rule vec_box * 💄 Fix clippy rule useless_format * 💄 Fix clippy rule unwrap_or_default * 💄 Fix clippy rule unused_unit * 💄 Fix clippy rule unnecessary_to_owned * 💄 Fix clippy rule too_many_arguments * 💄 Fix clippy rule slow_vector_initialization * 💄 Fix clippy rule single_match * 💄 Fix clippy rule redundant_field_names * 💄 Fix clippy rule rendudant_closure * 💄 Fix clippy rule needless_return * 💄 Fix clippy rule needless_range_loop * 💄 Fix clippy rule needless_borrows_for_generic_args * 💄 Fix clippy rule needless-borrow * 💄 Fix clippy rule missing_transmute_annotations * 💄 Fix clippy rule map_entry * 💄 Fix clippy rule manual_map * 💄 Fix clippy rule len_zero * 💄 Fix clippy rule from_over_into * 💄 Fix clippy rule field_reassign_with_default * 💄 Fix clippy rule enum_variant_names * 💄 Fix clippy rule derivable_impls * 💄 Fix clippy rule clone_on_copy * 💄 Fix clippy rule box_collection * 🔧 Make lint script also check test config target * 🔧 Remove cargo-watch as a lib dependency * 💄 Fix clippy rule for join_bounds * 🔧 Fix lint script return code --------- Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
This commit is contained in:
parent
051c2a7e99
commit
8afd217a80
35 changed files with 447 additions and 2338 deletions
|
@ -435,8 +435,7 @@ pub extern "C" fn propagate_apply() -> *mut u8 {
|
|||
let center = result_bound.center();
|
||||
let transform = result_bound.transform_matrix().unwrap_or(Matrix::default());
|
||||
|
||||
let mut bytes = Vec::<u8>::with_capacity(40);
|
||||
bytes.resize(40, 0);
|
||||
let mut bytes = vec![0; 40];
|
||||
bytes[0..4].clone_from_slice(&width.to_le_bytes());
|
||||
bytes[4..8].clone_from_slice(&height.to_le_bytes());
|
||||
bytes[8..12].clone_from_slice(¢er.x.to_le_bytes());
|
||||
|
@ -447,8 +446,9 @@ pub extern "C" fn propagate_apply() -> *mut u8 {
|
|||
bytes[28..32].clone_from_slice(&transform[4].to_le_bytes());
|
||||
bytes[32..36].clone_from_slice(&transform[2].to_le_bytes());
|
||||
bytes[36..40].clone_from_slice(&transform[5].to_le_bytes());
|
||||
return mem::write_bytes(bytes);
|
||||
});
|
||||
|
||||
mem::write_bytes(bytes)
|
||||
})
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -64,7 +64,7 @@ impl Bounds {
|
|||
Self { nw, ne, se, sw }
|
||||
}
|
||||
|
||||
pub fn join_bounds(bounds: &Vec<&Bounds>) -> Self {
|
||||
pub fn join_bounds(bounds: &[&Bounds]) -> Self {
|
||||
let (min_x, min_y, max_x, max_y) =
|
||||
bounds
|
||||
.iter()
|
||||
|
@ -133,11 +133,13 @@ impl Bounds {
|
|||
self.sw = mtx.map_point(self.sw);
|
||||
}
|
||||
|
||||
// FIXME: this looks like this should be a try_from static method or similar
|
||||
pub fn box_bounds(&self, other: &Self) -> Option<Self> {
|
||||
self.from_points(other.points())
|
||||
self.with_points(other.points())
|
||||
}
|
||||
|
||||
pub fn from_points(&self, points: Vec<Point>) -> Option<Self> {
|
||||
// FIXME: this looks like this should be a try_from static method or similar
|
||||
pub fn with_points(&self, points: Vec<Point>) -> Option<Self> {
|
||||
let hv = self.horizontal_vec();
|
||||
let vv = self.vertical_vec();
|
||||
|
||||
|
@ -312,17 +314,17 @@ impl Bounds {
|
|||
|
||||
// TODO: Probably we can improve performance here removing the access
|
||||
pub fn flip_x(&self) -> bool {
|
||||
let m = self.transform_matrix().unwrap_or(Matrix::default());
|
||||
let m = self.transform_matrix().unwrap_or_default();
|
||||
m.scale_x() < 0.0
|
||||
}
|
||||
|
||||
// TODO: Probably we can improve performance here removing the access
|
||||
pub fn flip_y(&self) -> bool {
|
||||
let m = self.transform_matrix().unwrap_or(Matrix::default());
|
||||
let m = self.transform_matrix().unwrap_or_default();
|
||||
m.scale_y() < 0.0
|
||||
}
|
||||
|
||||
pub fn to_rect(&self) -> Rect {
|
||||
pub fn to_rect(self) -> Rect {
|
||||
Rect::from_ltrb(self.min_x(), self.min_y(), self.max_x(), self.max_y())
|
||||
}
|
||||
|
||||
|
@ -387,11 +389,7 @@ pub fn intersect_rays_t(ray1: &Ray, ray2: &Ray) -> Option<f32> {
|
|||
}
|
||||
|
||||
pub fn intersect_rays(ray1: &Ray, ray2: &Ray) -> Option<Point> {
|
||||
if let Some(t) = intersect_rays_t(ray1, ray2) {
|
||||
Some(ray1.t(t))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
intersect_rays_t(ray1, ray2).map(|t| ray1.t(t))
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -409,9 +407,7 @@ pub fn resize_matrix(
|
|||
let scale_height = new_height / child_bounds.height();
|
||||
|
||||
let center = child_bounds.center();
|
||||
let mut parent_transform = parent_bounds
|
||||
.transform_matrix()
|
||||
.unwrap_or(Matrix::default());
|
||||
let mut parent_transform = parent_bounds.transform_matrix().unwrap_or_default();
|
||||
|
||||
parent_transform.post_translate(center);
|
||||
parent_transform.pre_translate(-center);
|
||||
|
@ -423,7 +419,7 @@ pub fn resize_matrix(
|
|||
scale.post_translate(origin);
|
||||
scale.post_concat(&parent_transform);
|
||||
scale.pre_translate(-origin);
|
||||
scale.pre_concat(&parent_transform_inv);
|
||||
scale.pre_concat(parent_transform_inv);
|
||||
result.post_concat(&scale);
|
||||
result
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::Mutex;
|
|||
|
||||
const LAYOUT_ALIGN: usize = 4;
|
||||
|
||||
static BUFFERU8: Mutex<Option<Box<Vec<u8>>>> = Mutex::new(None);
|
||||
static BUFFERU8: Mutex<Option<Vec<u8>>> = Mutex::new(None);
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn alloc_bytes(len: usize) -> *mut u8 {
|
||||
|
@ -16,28 +16,27 @@ pub extern "C" fn alloc_bytes(len: usize) -> *mut u8 {
|
|||
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align_unchecked(len, LAYOUT_ALIGN);
|
||||
let ptr = alloc(layout) as *mut u8;
|
||||
let ptr = alloc(layout);
|
||||
if ptr.is_null() {
|
||||
panic!("Allocation failed");
|
||||
}
|
||||
// TODO: Maybe this could be removed.
|
||||
ptr::write_bytes(ptr, 0, len);
|
||||
*guard = Some(Box::new(Vec::from_raw_parts(ptr, len, len)));
|
||||
*guard = Some(Vec::from_raw_parts(ptr, len, len));
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_bytes(bytes: Vec<u8>) -> *mut u8 {
|
||||
pub fn write_bytes(mut bytes: Vec<u8>) -> *mut u8 {
|
||||
let mut guard = BUFFERU8.lock().unwrap();
|
||||
|
||||
if guard.is_some() {
|
||||
panic!("Bytes already allocated");
|
||||
}
|
||||
|
||||
let mut new_buffer = Box::new(bytes);
|
||||
let ptr = new_buffer.as_mut_ptr();
|
||||
let ptr = bytes.as_mut_ptr();
|
||||
|
||||
*guard = Some(new_buffer);
|
||||
*guard = Some(bytes);
|
||||
ptr
|
||||
}
|
||||
|
||||
|
@ -50,16 +49,12 @@ pub extern "C" fn free_bytes() {
|
|||
|
||||
pub fn bytes() -> Vec<u8> {
|
||||
let mut guard = BUFFERU8.lock().unwrap();
|
||||
|
||||
guard
|
||||
.take()
|
||||
.map_or_else(|| panic!("Buffer is not initialized"), |buffer| *buffer)
|
||||
guard.take().expect("Buffer is not initialized")
|
||||
}
|
||||
|
||||
pub fn bytes_or_empty() -> Vec<u8> {
|
||||
let mut guard = BUFFERU8.lock().unwrap();
|
||||
|
||||
guard.take().map_or_else(|| Vec::new(), |buffer| *buffer)
|
||||
guard.take().unwrap_or_default()
|
||||
}
|
||||
|
||||
pub trait SerializableResult {
|
||||
|
@ -77,14 +72,13 @@ pub trait SerializableResult {
|
|||
pub fn write_vec<T: SerializableResult>(result: Vec<T>) -> *mut u8 {
|
||||
let elem_size = size_of::<T::BytesType>();
|
||||
let bytes_len = 4 + result.len() * elem_size;
|
||||
let mut result_bytes = Vec::<u8>::with_capacity(bytes_len);
|
||||
let mut result_bytes = vec![0; bytes_len];
|
||||
|
||||
result_bytes.resize(bytes_len, 0);
|
||||
result_bytes[0..4].clone_from_slice(&result.len().to_le_bytes());
|
||||
|
||||
for i in 0..result.len() {
|
||||
for (i, item) in result.iter().enumerate() {
|
||||
let base = 4 + i * elem_size;
|
||||
result[i].clone_to_slice(&mut result_bytes[base..base + elem_size]);
|
||||
item.clone_to_slice(&mut result_bytes[base..base + elem_size]);
|
||||
}
|
||||
|
||||
write_bytes(result_bytes)
|
||||
|
|
|
@ -20,7 +20,7 @@ macro_rules! mark {
|
|||
($name:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::run_script;
|
||||
use $crate::run_script;
|
||||
run_script!(format!("performance.mark('{}')", $name));
|
||||
}
|
||||
};
|
||||
|
@ -31,14 +31,14 @@ macro_rules! measure {
|
|||
($name:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::run_script;
|
||||
use $crate::run_script;
|
||||
run_script!(format!("performance.measure('{}')", $name));
|
||||
}
|
||||
};
|
||||
($name:expr, $mark_begin:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::run_script;
|
||||
use $crate::run_script;
|
||||
run_script!(format!(
|
||||
"performance.measure('{}','{}')",
|
||||
$name, $mark_begin
|
||||
|
@ -48,7 +48,7 @@ macro_rules! measure {
|
|||
($name:expr, $mark_begin:expr, $mark_end:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::run_script;
|
||||
use $crate::run_script;
|
||||
run_script!(format!(
|
||||
"performance.measure('{}','{}','{}')",
|
||||
$name, $mark_begin, $mark_end
|
||||
|
@ -76,7 +76,7 @@ macro_rules! measure_marks {
|
|||
($name:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::{begin_mark_name, end_mark_name, measure};
|
||||
use $crate::{begin_mark_name, end_mark_name, measure};
|
||||
measure!($name, begin_mark_name!($name), end_mark_name!($name));
|
||||
}
|
||||
};
|
||||
|
@ -85,7 +85,7 @@ macro_rules! measure_marks {
|
|||
#[macro_export]
|
||||
macro_rules! clear_marks {
|
||||
() => {
|
||||
use crate::run_script;
|
||||
use $crate::run_script;
|
||||
run_script!("performance.clearMarks()");
|
||||
};
|
||||
($($name:expr),*) => {
|
||||
|
@ -96,7 +96,7 @@ macro_rules! clear_marks {
|
|||
#[macro_export]
|
||||
macro_rules! clear_measures {
|
||||
() => {
|
||||
use crate::run_script;
|
||||
use $crate::run_script;
|
||||
run_script!("performance.clearMeasures()");
|
||||
};
|
||||
($($name:expr),*) => {
|
||||
|
@ -109,14 +109,14 @@ macro_rules! begin_measure {
|
|||
($name:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::{begin_mark_name, mark};
|
||||
use $crate::{begin_mark_name, mark};
|
||||
mark!(begin_mark_name!($name));
|
||||
}
|
||||
};
|
||||
($name:expr, $clear_marks:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::{begin_mark_name, clear_marks, end_mark_name, mark};
|
||||
use $crate::{begin_mark_name, clear_marks, end_mark_name, mark};
|
||||
if $clear_marks {
|
||||
clear_marks!(begin_mark_name!($name), end_mark_name($name));
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ macro_rules! end_measure {
|
|||
($name:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::{end_mark_name, mark, measure_marks};
|
||||
use $crate::{end_mark_name, mark, measure_marks};
|
||||
mark!(end_mark_name!($name));
|
||||
measure_marks!($name);
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ macro_rules! end_measure {
|
|||
($name:expr, $clear_marks:expr) => {
|
||||
#[cfg(all(feature = "profile-macros", target_arch = "wasm32"))]
|
||||
{
|
||||
use crate::{begin_mark_name, clear_marks, end_mark_name, mark, measure_marks};
|
||||
use $crate::{begin_mark_name, clear_marks, end_mark_name, mark, measure_marks};
|
||||
mark!(end_mark_name!($name));
|
||||
measure_marks!($name);
|
||||
if $clear_marks {
|
||||
|
|
|
@ -343,7 +343,7 @@ impl RenderState {
|
|||
let mut shape = shape.clone();
|
||||
|
||||
if let Some(modifiers) = modifiers {
|
||||
shape.apply_transform(&modifiers);
|
||||
shape.apply_transform(modifiers);
|
||||
}
|
||||
|
||||
let center = shape.center();
|
||||
|
@ -354,14 +354,14 @@ impl RenderState {
|
|||
match &shape.shape_type {
|
||||
Type::SVGRaw(sr) => {
|
||||
if let Some(modifiers) = modifiers {
|
||||
self.surfaces.canvas(SurfaceId::Fills).concat(&modifiers);
|
||||
self.surfaces.canvas(SurfaceId::Fills).concat(modifiers);
|
||||
}
|
||||
self.surfaces.canvas(SurfaceId::Fills).concat(&matrix);
|
||||
if let Some(svg) = shape.svg.as_ref() {
|
||||
svg.render(self.surfaces.canvas(SurfaceId::Fills))
|
||||
} else {
|
||||
let font_manager = skia::FontMgr::from(self.fonts().font_provider().clone());
|
||||
let dom_result = skia::svg::Dom::from_str(sr.content.to_string(), font_manager);
|
||||
let dom_result = skia::svg::Dom::from_str(&sr.content, font_manager);
|
||||
match dom_result {
|
||||
Ok(dom) => {
|
||||
dom.render(self.surfaces.canvas(SurfaceId::Fills));
|
||||
|
@ -380,7 +380,7 @@ impl RenderState {
|
|||
});
|
||||
|
||||
let text_content = text_content.new_bounds(shape.selrect());
|
||||
let paragraphs = text_content.get_skia_paragraphs(&self.fonts.font_collection());
|
||||
let paragraphs = text_content.get_skia_paragraphs(self.fonts.font_collection());
|
||||
|
||||
shadows::render_text_drop_shadows(self, &shape, ¶graphs, antialias);
|
||||
text::render(self, &shape, ¶graphs, None, None);
|
||||
|
@ -390,9 +390,9 @@ impl RenderState {
|
|||
if let Fill::Image(image_fill) = &stroke.fill {
|
||||
image = self.images.get(&image_fill.id()).cloned();
|
||||
}
|
||||
let stroke_paints = shape.get_text_stroke_paint(&stroke, image.as_ref());
|
||||
let stroke_paints = shape.get_text_stroke_paint(stroke, image.as_ref());
|
||||
let stroke_paragraphs = text_content
|
||||
.get_skia_stroke_paragraphs(&self.fonts.font_collection(), &stroke_paints);
|
||||
.get_skia_stroke_paragraphs(self.fonts.font_collection(), &stroke_paints);
|
||||
shadows::render_text_drop_shadows(self, &shape, &stroke_paragraphs, antialias);
|
||||
text::render(
|
||||
self,
|
||||
|
@ -602,17 +602,14 @@ impl RenderState {
|
|||
// the content and the second one rendering the mask so we need to do
|
||||
// an extra save_layer to keep all the masked group separate from
|
||||
// other already drawn elements.
|
||||
match element.shape_type {
|
||||
Type::Group(group) => {
|
||||
if group.masked {
|
||||
let paint = skia::Paint::default();
|
||||
let layer_rec = skia::canvas::SaveLayerRec::default().paint(&paint);
|
||||
self.surfaces
|
||||
.canvas(SurfaceId::Current)
|
||||
.save_layer(&layer_rec);
|
||||
}
|
||||
if let Type::Group(group) = element.shape_type {
|
||||
if group.masked {
|
||||
let paint = skia::Paint::default();
|
||||
let layer_rec = skia::canvas::SaveLayerRec::default().paint(&paint);
|
||||
self.surfaces
|
||||
.canvas(SurfaceId::Current)
|
||||
.save_layer(&layer_rec);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let mut paint = skia::Paint::default();
|
||||
|
@ -646,13 +643,10 @@ impl RenderState {
|
|||
// Because masked groups needs two rendering passes (first drawing
|
||||
// the content and then drawing the mask), we need to do an
|
||||
// extra restore.
|
||||
match element.shape_type {
|
||||
Type::Group(group) => {
|
||||
if group.masked {
|
||||
self.surfaces.canvas(SurfaceId::Current).restore();
|
||||
}
|
||||
if let Type::Group(group) = element.shape_type {
|
||||
if group.masked {
|
||||
self.surfaces.canvas(SurfaceId::Current).restore();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.surfaces.canvas(SurfaceId::Current).restore();
|
||||
|
@ -746,39 +740,36 @@ impl RenderState {
|
|||
|
||||
// If the shape is not in the tile set, then we update
|
||||
// it.
|
||||
if let None = self.tiles.get_tiles_of(node_id) {
|
||||
if self.tiles.get_tiles_of(node_id).is_none() {
|
||||
self.update_tile_for(element);
|
||||
}
|
||||
|
||||
if visited_children {
|
||||
if !visited_mask {
|
||||
match element.shape_type {
|
||||
Type::Group(group) => {
|
||||
// When we're dealing with masked groups we need to
|
||||
// do a separate extra step to draw the mask (the last
|
||||
// element of a masked group) and blend (using
|
||||
// the blend mode 'destination-in') the content
|
||||
// of the group and the mask.
|
||||
if group.masked {
|
||||
if let Type::Group(group) = element.shape_type {
|
||||
// When we're dealing with masked groups we need to
|
||||
// do a separate extra step to draw the mask (the last
|
||||
// element of a masked group) and blend (using
|
||||
// the blend mode 'destination-in') the content
|
||||
// of the group and the mask.
|
||||
if group.masked {
|
||||
self.pending_nodes.push(NodeRenderState {
|
||||
id: node_id,
|
||||
visited_children: true,
|
||||
clip_bounds: None,
|
||||
visited_mask: true,
|
||||
mask: false,
|
||||
});
|
||||
if let Some(&mask_id) = element.mask_id() {
|
||||
self.pending_nodes.push(NodeRenderState {
|
||||
id: node_id,
|
||||
visited_children: true,
|
||||
id: mask_id,
|
||||
visited_children: false,
|
||||
clip_bounds: None,
|
||||
visited_mask: true,
|
||||
mask: false,
|
||||
visited_mask: false,
|
||||
mask: true,
|
||||
});
|
||||
if let Some(&mask_id) = element.mask_id() {
|
||||
self.pending_nodes.push(NodeRenderState {
|
||||
id: mask_id,
|
||||
visited_children: false,
|
||||
clip_bounds: None,
|
||||
visited_mask: false,
|
||||
mask: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.render_shape_exit(element, visited_mask);
|
||||
|
@ -806,7 +797,7 @@ impl RenderState {
|
|||
if !node_render_state.id.is_nil() {
|
||||
self.render_shape(element, modifiers.get(&element.id), clip_bounds);
|
||||
} else {
|
||||
self.apply_drawing_to_render_canvas(Some(&element));
|
||||
self.apply_drawing_to_render_canvas(Some(element));
|
||||
}
|
||||
|
||||
// Set the node as visited_children before processing children
|
||||
|
@ -815,7 +806,7 @@ impl RenderState {
|
|||
visited_children: true,
|
||||
clip_bounds: None,
|
||||
visited_mask: false,
|
||||
mask: mask,
|
||||
mask,
|
||||
});
|
||||
|
||||
if element.is_recursive() {
|
||||
|
@ -874,7 +865,7 @@ impl RenderState {
|
|||
let Some(root) = tree.get(&Uuid::nil()) else {
|
||||
return Err(String::from("Root shape not found"));
|
||||
};
|
||||
let root_ids = modified_children_ids(&root, structure.get(&root.id));
|
||||
let root_ids = modified_children_ids(root, structure.get(&root.id));
|
||||
|
||||
// If we finish processing every node rendering is complete
|
||||
// let's check if there are more pending nodes
|
||||
|
@ -912,7 +903,7 @@ impl RenderState {
|
|||
self.render_in_progress = false;
|
||||
|
||||
// Cache target surface in a texture
|
||||
self.cached_viewbox = self.viewbox.clone();
|
||||
self.cached_viewbox = self.viewbox;
|
||||
self.cached_target_snapshot = Some(self.surfaces.snapshot(SurfaceId::Cache));
|
||||
|
||||
if self.options.is_debug_visible() {
|
||||
|
|
|
@ -12,17 +12,17 @@ impl Default for BlendMode {
|
|||
impl From<i32> for BlendMode {
|
||||
fn from(value: i32) -> Self {
|
||||
if value <= skia::BlendMode::Luminosity as i32 {
|
||||
unsafe { Self(std::mem::transmute(value)) }
|
||||
unsafe { Self(std::mem::transmute::<i32, skia_safe::BlendMode>(value)) }
|
||||
} else {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<skia::BlendMode> for BlendMode {
|
||||
fn into(self) -> skia::BlendMode {
|
||||
match self {
|
||||
Self(skia_blend) => skia_blend,
|
||||
impl From<BlendMode> for skia::BlendMode {
|
||||
fn from(val: BlendMode) -> Self {
|
||||
match val {
|
||||
BlendMode(skia_blend) => skia_blend,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ fn render_debug_view(render_state: &mut RenderState) {
|
|||
paint.set_color(skia::Color::from_rgb(255, 0, 255));
|
||||
paint.set_stroke_width(1.);
|
||||
|
||||
let rect = get_debug_rect(render_state.viewbox.area.clone());
|
||||
let rect = get_debug_rect(render_state.viewbox.area);
|
||||
render_state
|
||||
.surfaces
|
||||
.canvas(SurfaceId::Debug)
|
||||
|
@ -55,7 +55,7 @@ pub fn render_wasm_label(render_state: &mut RenderState) {
|
|||
let p = skia::Point::new(width as f32 - 25.0 - scalar, height as f32 - 25.0);
|
||||
|
||||
let debug_font = render_state.fonts.debug_font();
|
||||
canvas.draw_str(str, p, &debug_font, &paint);
|
||||
canvas.draw_str(str, p, debug_font, &paint);
|
||||
}
|
||||
|
||||
pub fn render_debug_shape(render_state: &mut RenderState, element: &Shape, intersected: bool) {
|
||||
|
@ -90,12 +90,7 @@ pub fn render_debug_tiles_for_viewbox(
|
|||
let str_rect = format!("{} {} {} {}", sx, sy, ex, ey);
|
||||
|
||||
let debug_font = render_state.fonts.debug_font();
|
||||
canvas.draw_str(
|
||||
str_rect,
|
||||
skia::Point::new(100.0, 150.0),
|
||||
&debug_font,
|
||||
&paint,
|
||||
);
|
||||
canvas.draw_str(str_rect, skia::Point::new(100.0, 150.0), debug_font, &paint);
|
||||
}
|
||||
|
||||
// Renders the tiles in the viewbox
|
||||
|
@ -111,12 +106,7 @@ pub fn render_debug_viewbox_tiles(render_state: &mut RenderState) {
|
|||
let str_rect = format!("{} {} {} {}", sx, sy, ex, ey);
|
||||
|
||||
let debug_font = render_state.fonts.debug_font();
|
||||
canvas.draw_str(
|
||||
str_rect,
|
||||
skia::Point::new(100.0, 100.0),
|
||||
&debug_font,
|
||||
&paint,
|
||||
);
|
||||
canvas.draw_str(str_rect, skia::Point::new(100.0, 100.0), debug_font, &paint);
|
||||
|
||||
let tile_size = tiles::get_tile_size(scale);
|
||||
for y in sy..=ey {
|
||||
|
@ -131,8 +121,8 @@ pub fn render_debug_viewbox_tiles(render_state: &mut RenderState) {
|
|||
let p = skia::Point::new(debug_rect.x(), debug_rect.y() - 1.);
|
||||
let str = format!("{}:{}", x, y);
|
||||
let debug_font = render_state.fonts.debug_font();
|
||||
canvas.draw_str(str, p, &debug_font, &paint);
|
||||
canvas.draw_rect(&debug_rect, &paint);
|
||||
canvas.draw_str(str, p, debug_font, &paint);
|
||||
canvas.draw_rect(debug_rect, &paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,8 +156,8 @@ pub fn render_debug_tiles(render_state: &mut RenderState) {
|
|||
let str = format!("{}:{} {}", x, y, shape_count);
|
||||
|
||||
let debug_font = render_state.fonts.debug_font();
|
||||
canvas.draw_str(str, p, &debug_font, &paint);
|
||||
canvas.draw_rect(&debug_rect, &paint);
|
||||
canvas.draw_str(str, p, debug_font, &paint);
|
||||
canvas.draw_rect(debug_rect, &paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,11 +209,11 @@ pub fn render_workspace_current_tile(
|
|||
let mut p = skia::Paint::default();
|
||||
p.set_stroke_width(1.);
|
||||
p.set_style(skia::PaintStyle::Stroke);
|
||||
canvas.draw_rect(&rect, &p);
|
||||
canvas.draw_rect(rect, &p);
|
||||
|
||||
let point = skia::Point::new(rect.x() + 10., rect.y() + 20.);
|
||||
p.set_stroke_width(1.);
|
||||
let str = format!("{prefix} {}:{}", tile.0, tile.1);
|
||||
let debug_font = render_state.fonts.debug_font();
|
||||
canvas.draw_str(str, point, &debug_font, &p);
|
||||
canvas.draw_str(str, point, debug_font, &p);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ fn draw_image_fill(
|
|||
corners: Some(corners),
|
||||
..
|
||||
}) => {
|
||||
let rrect: RRect = RRect::new_rect_radii(container, &corners);
|
||||
let rrect: RRect = RRect::new_rect_radii(container, corners);
|
||||
canvas.clip_rrect(rrect, skia::ClipOp::Intersect, antialias);
|
||||
}
|
||||
Type::Rect(_) | Type::Frame(_) => {
|
||||
|
@ -77,7 +77,7 @@ fn draw_image_fill(
|
|||
if let Some(path) = shape_type.path() {
|
||||
if let Some(path_transform) = path_transform {
|
||||
canvas.clip_path(
|
||||
&path.to_skia_path().transform(&path_transform),
|
||||
path.to_skia_path().transform(&path_transform),
|
||||
skia::ClipOp::Intersect,
|
||||
antialias,
|
||||
);
|
||||
|
@ -98,7 +98,7 @@ fn draw_image_fill(
|
|||
None,
|
||||
dest_rect,
|
||||
render_state.sampling_options,
|
||||
&paint,
|
||||
paint,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use skia_safe::{self as skia, textlayout, Font, FontMgr};
|
|||
use crate::shapes::{FontFamily, FontStyle};
|
||||
use crate::uuid::Uuid;
|
||||
|
||||
pub static DEFAULT_EMOJI_FONT: &'static str = "noto-color-emoji";
|
||||
pub static DEFAULT_EMOJI_FONT: &str = "noto-color-emoji";
|
||||
|
||||
const DEFAULT_FONT_BYTES: &[u8] = include_bytes!("../fonts/sourcesanspro-regular.ttf");
|
||||
|
||||
|
|
|
@ -1,20 +1,11 @@
|
|||
use crate::options;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Default)]
|
||||
pub struct RenderOptions {
|
||||
pub flags: u32,
|
||||
pub dpr: Option<f32>,
|
||||
}
|
||||
|
||||
impl Default for RenderOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
flags: 0x00,
|
||||
dpr: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOptions {
|
||||
pub fn is_debug_visible(&self) -> bool {
|
||||
self.flags & options::DEBUG_VISIBLE == options::DEBUG_VISIBLE
|
||||
|
|
|
@ -8,7 +8,7 @@ use skia_safe::{textlayout::Paragraph, Paint};
|
|||
pub fn render_fill_drop_shadows(render_state: &mut RenderState, shape: &Shape, antialias: bool) {
|
||||
if shape.has_fills() {
|
||||
for shadow in shape.drop_shadows().rev().filter(|s| !s.hidden()) {
|
||||
render_fill_drop_shadow(render_state, &shape, &shadow, antialias);
|
||||
render_fill_drop_shadow(render_state, shape, shadow, antialias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ fn render_fill_drop_shadow(
|
|||
pub fn render_fill_inner_shadows(render_state: &mut RenderState, shape: &Shape, antialias: bool) {
|
||||
if shape.has_fills() {
|
||||
for shadow in shape.inner_shadows().rev().filter(|s| !s.hidden()) {
|
||||
render_fill_inner_shadow(render_state, &shape, &shadow, antialias);
|
||||
render_fill_inner_shadow(render_state, shape, shadow, antialias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ pub fn render_stroke_drop_shadows(
|
|||
let filter = shadow.get_drop_shadow_filter();
|
||||
strokes::render(
|
||||
render_state,
|
||||
&shape,
|
||||
shape,
|
||||
stroke,
|
||||
Some(SurfaceId::Strokes), // FIXME
|
||||
filter.as_ref(),
|
||||
|
@ -73,7 +73,7 @@ pub fn render_stroke_inner_shadows(
|
|||
let filter = shadow.get_inner_shadow_filter();
|
||||
strokes::render(
|
||||
render_state,
|
||||
&shape,
|
||||
shape,
|
||||
stroke,
|
||||
Some(SurfaceId::Strokes), // FIXME
|
||||
filter.as_ref(),
|
||||
|
@ -90,7 +90,7 @@ pub fn render_text_drop_shadows(
|
|||
antialias: bool,
|
||||
) {
|
||||
for shadow in shape.drop_shadows().rev().filter(|s| !s.hidden()) {
|
||||
render_text_drop_shadow(render_state, &shape, &shadow, ¶graphs, antialias);
|
||||
render_text_drop_shadow(render_state, shape, shadow, paragraphs, antialias);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,12 +101,12 @@ pub fn render_text_drop_shadow(
|
|||
paragraphs: &[Vec<Paragraph>],
|
||||
antialias: bool,
|
||||
) {
|
||||
let paint = &shadow.get_drop_shadow_paint(antialias);
|
||||
let paint = shadow.get_drop_shadow_paint(antialias);
|
||||
|
||||
text::render(
|
||||
render_state,
|
||||
shape,
|
||||
¶graphs,
|
||||
paragraphs,
|
||||
Some(SurfaceId::DropShadows),
|
||||
Some(paint),
|
||||
);
|
||||
|
@ -119,7 +119,7 @@ pub fn render_text_inner_shadows(
|
|||
antialias: bool,
|
||||
) {
|
||||
for shadow in shape.inner_shadows().rev().filter(|s| !s.hidden()) {
|
||||
render_text_inner_shadow(render_state, &shape, &shadow, ¶graphs, antialias);
|
||||
render_text_inner_shadow(render_state, shape, shadow, paragraphs, antialias);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,12 +130,12 @@ pub fn render_text_inner_shadow(
|
|||
paragraphs: &[Vec<Paragraph>],
|
||||
antialias: bool,
|
||||
) {
|
||||
let paint = &shadow.get_inner_shadow_paint(antialias);
|
||||
let paint = shadow.get_inner_shadow_paint(antialias);
|
||||
|
||||
text::render(
|
||||
render_state,
|
||||
shape,
|
||||
¶graphs,
|
||||
paragraphs,
|
||||
Some(SurfaceId::InnerShadows),
|
||||
Some(paint),
|
||||
);
|
||||
|
|
|
@ -7,6 +7,8 @@ use skia_safe::{self as skia, ImageFilter, RRect};
|
|||
|
||||
use super::{RenderState, SurfaceId};
|
||||
|
||||
// FIXME: See if we can simplify these arguments
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw_stroke_on_rect(
|
||||
canvas: &skia::Canvas,
|
||||
stroke: &Stroke,
|
||||
|
@ -36,11 +38,13 @@ fn draw_stroke_on_rect(
|
|||
canvas.draw_rrect(rrect, &paint);
|
||||
}
|
||||
None => {
|
||||
canvas.draw_rect(&stroke_rect, &paint);
|
||||
canvas.draw_rect(stroke_rect, &paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: See if we can simplify these arguments
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw_stroke_on_circle(
|
||||
canvas: &skia::Canvas,
|
||||
stroke: &Stroke,
|
||||
|
@ -62,9 +66,11 @@ fn draw_stroke_on_circle(
|
|||
paint.set_image_filter(filter.clone());
|
||||
}
|
||||
|
||||
canvas.draw_oval(&stroke_rect, &paint);
|
||||
canvas.draw_oval(stroke_rect, &paint);
|
||||
}
|
||||
|
||||
// FIXME: See if we can simplify these arguments
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn draw_stroke_on_path(
|
||||
canvas: &skia::Canvas,
|
||||
stroke: &Stroke,
|
||||
|
@ -90,18 +96,18 @@ pub fn draw_stroke_on_path(
|
|||
// Draw the different kind of strokes for a path requires different strategies:
|
||||
match stroke.render_kind(is_open) {
|
||||
// For inner stroke we draw a center stroke (with double width) and clip to the original path (that way the extra outer stroke is removed)
|
||||
StrokeKind::InnerStroke => {
|
||||
StrokeKind::Inner => {
|
||||
canvas.save(); // As we are using clear for surfaces we use save and restore here to still be able to clean the full surface
|
||||
canvas.clip_path(&skia_path, skia::ClipOp::Intersect, antialias);
|
||||
canvas.draw_path(&skia_path, &paint);
|
||||
canvas.restore();
|
||||
}
|
||||
// For center stroke we don't need to do anything extra
|
||||
StrokeKind::CenterStroke => {
|
||||
StrokeKind::Center => {
|
||||
canvas.draw_path(&skia_path, &paint);
|
||||
}
|
||||
// For outer stroke we draw a center stroke (with double width) and use another path with blend mode clear to remove the inner stroke added
|
||||
StrokeKind::OuterStroke => {
|
||||
StrokeKind::Outer => {
|
||||
let mut outer_paint = skia::Paint::default();
|
||||
outer_paint.set_blend_mode(skia::BlendMode::SrcOver);
|
||||
outer_paint.set_anti_alias(antialias);
|
||||
|
@ -121,7 +127,7 @@ pub fn draw_stroke_on_path(
|
|||
handle_stroke_caps(
|
||||
&mut skia_path,
|
||||
stroke,
|
||||
&selrect,
|
||||
selrect,
|
||||
canvas,
|
||||
is_open,
|
||||
svg_attrs,
|
||||
|
@ -144,31 +150,33 @@ fn handle_stroke_cap(
|
|||
StrokeCap::None => {}
|
||||
StrokeCap::Line => {
|
||||
// We also draw this square cap to fill the gap between the path and the arrow
|
||||
draw_square_cap(canvas, &paint, p1, p2, width, 0.);
|
||||
draw_square_cap(canvas, paint, p1, p2, width, 0.);
|
||||
paint.set_style(skia::PaintStyle::Stroke);
|
||||
draw_arrow_cap(canvas, &paint, p1, p2, width * 4.);
|
||||
draw_arrow_cap(canvas, paint, p1, p2, width * 4.);
|
||||
}
|
||||
StrokeCap::Triangle => {
|
||||
draw_triangle_cap(canvas, &paint, p1, p2, width * 4.);
|
||||
draw_triangle_cap(canvas, paint, p1, p2, width * 4.);
|
||||
}
|
||||
StrokeCap::Rectangle => {
|
||||
draw_square_cap(canvas, &paint, p1, p2, width * 4., 0.);
|
||||
draw_square_cap(canvas, paint, p1, p2, width * 4., 0.);
|
||||
}
|
||||
StrokeCap::Circle => {
|
||||
canvas.draw_circle((p1.x, p1.y), width * 2., &paint);
|
||||
canvas.draw_circle((p1.x, p1.y), width * 2., paint);
|
||||
}
|
||||
StrokeCap::Diamond => {
|
||||
draw_square_cap(canvas, &paint, p1, p2, width * 4., 45.);
|
||||
draw_square_cap(canvas, paint, p1, p2, width * 4., 45.);
|
||||
}
|
||||
StrokeCap::Round => {
|
||||
canvas.draw_circle((p1.x, p1.y), width / 2.0, &paint);
|
||||
canvas.draw_circle((p1.x, p1.y), width / 2.0, paint);
|
||||
}
|
||||
StrokeCap::Square => {
|
||||
draw_square_cap(canvas, &paint, p1, p2, width, 0.);
|
||||
draw_square_cap(canvas, paint, p1, p2, width, 0.);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: See if we can simplify these arguments
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn handle_stroke_caps(
|
||||
path: &mut skia::Path,
|
||||
stroke: &Stroke,
|
||||
|
@ -238,7 +246,7 @@ fn draw_square_cap(
|
|||
Point::new(rect.left(), rect.bottom()),
|
||||
];
|
||||
|
||||
let mut transformed_points = points.clone();
|
||||
let mut transformed_points = points;
|
||||
matrix.map_points(&mut transformed_points, &points);
|
||||
|
||||
let mut path = skia::Path::new();
|
||||
|
@ -272,7 +280,7 @@ fn draw_arrow_cap(
|
|||
Point::new(center.x + size, center.y + half_height),
|
||||
];
|
||||
|
||||
let mut transformed_points = points.clone();
|
||||
let mut transformed_points = points;
|
||||
matrix.map_points(&mut transformed_points, &points);
|
||||
|
||||
let mut path = skia::Path::new();
|
||||
|
@ -306,7 +314,7 @@ fn draw_triangle_cap(
|
|||
Point::new(center.x + size, center.y + half_height),
|
||||
];
|
||||
|
||||
let mut transformed_points = points.clone();
|
||||
let mut transformed_points = points;
|
||||
matrix.map_points(&mut transformed_points, &points);
|
||||
|
||||
let mut path = skia::Path::new();
|
||||
|
@ -406,11 +414,11 @@ fn draw_image_stroke_in_container(
|
|||
path.transform(&path_transform.unwrap());
|
||||
let stroke_kind = stroke.render_kind(p.is_open());
|
||||
match stroke_kind {
|
||||
StrokeKind::InnerStroke => {
|
||||
StrokeKind::Inner => {
|
||||
canvas.clip_path(&path, skia::ClipOp::Intersect, antialias);
|
||||
}
|
||||
StrokeKind::CenterStroke => {}
|
||||
StrokeKind::OuterStroke => {
|
||||
StrokeKind::Center => {}
|
||||
StrokeKind::Outer => {
|
||||
canvas.clip_path(&path, skia::ClipOp::Difference, antialias);
|
||||
}
|
||||
}
|
||||
|
@ -418,7 +426,7 @@ fn draw_image_stroke_in_container(
|
|||
let mut paint =
|
||||
stroke.to_stroked_paint(is_open, &outer_rect, svg_attrs, scale, antialias);
|
||||
canvas.draw_path(&path, &paint);
|
||||
if stroke.render_kind(is_open) == StrokeKind::OuterStroke {
|
||||
if stroke.render_kind(is_open) == StrokeKind::Outer {
|
||||
// Small extra inner stroke to overlap with the fill
|
||||
// and avoid unnecesary artifacts.
|
||||
paint.set_stroke_width(1. / scale);
|
||||
|
@ -461,7 +469,7 @@ fn draw_image_stroke_in_container(
|
|||
|
||||
// Clear outer stroke for paths if necessary. When adding an outer stroke we need to empty the stroke added too in the inner area.
|
||||
if let Type::Path(p) = &shape.shape_type {
|
||||
if stroke.render_kind(p.is_open()) == StrokeKind::OuterStroke {
|
||||
if stroke.render_kind(p.is_open()) == StrokeKind::Outer {
|
||||
let mut path = p.to_skia_path();
|
||||
path.transform(&path_transform.unwrap());
|
||||
let mut clear_paint = skia::Paint::default();
|
||||
|
@ -494,7 +502,7 @@ pub fn render(
|
|||
let path_transform = shape.to_path_transform();
|
||||
let svg_attrs = &shape.svg_attrs;
|
||||
|
||||
if !shadow.is_some() && matches!(stroke.fill, Fill::Image(_)) {
|
||||
if shadow.is_none() && matches!(stroke.fill, Fill::Image(_)) {
|
||||
if let Fill::Image(image_fill) = &stroke.fill {
|
||||
draw_image_stroke_in_container(render_state, shape, stroke, image_fill, antialias);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ impl Surfaces {
|
|||
let encoded_image = image
|
||||
.encode(context.as_mut(), skia::EncodedImageFormat::PNG, None)
|
||||
.unwrap();
|
||||
general_purpose::STANDARD.encode(&encoded_image.as_bytes())
|
||||
general_purpose::STANDARD.encode(encoded_image.as_bytes())
|
||||
}
|
||||
|
||||
pub fn base64_snapshot_rect(&mut self, id: SurfaceId, irect: skia::IRect) -> Option<String> {
|
||||
|
@ -115,7 +115,7 @@ impl Surfaces {
|
|||
let encoded_image = image
|
||||
.encode(context.as_mut(), skia::EncodedImageFormat::PNG, None)
|
||||
.unwrap();
|
||||
return Some(general_purpose::STANDARD.encode(&encoded_image.as_bytes()));
|
||||
return Some(general_purpose::STANDARD.encode(encoded_image.as_bytes()));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ impl Surfaces {
|
|||
.draw(self.canvas(to), (0.0, 0.0), sampling_options, paint);
|
||||
}
|
||||
|
||||
pub fn apply_mut(&mut self, ids: &[SurfaceId], mut f: impl FnMut(&mut skia::Surface) -> ()) {
|
||||
pub fn apply_mut(&mut self, ids: &[SurfaceId], mut f: impl FnMut(&mut skia::Surface)) {
|
||||
for id in ids {
|
||||
let surface = self.get_mut(*id);
|
||||
f(surface);
|
||||
|
@ -257,10 +257,10 @@ impl Surfaces {
|
|||
self.current.height() - TILE_SIZE_MULTIPLIER * self.margins.height,
|
||||
);
|
||||
|
||||
if let Some(snapshot) = self.current.image_snapshot_with_bounds(&rect) {
|
||||
if let Some(snapshot) = self.current.image_snapshot_with_bounds(rect) {
|
||||
self.tiles.add(tile, snapshot.clone());
|
||||
self.cache.canvas().draw_image_rect(
|
||||
&snapshot.clone(),
|
||||
snapshot.clone(),
|
||||
None,
|
||||
tile_rect,
|
||||
&skia::Paint::default(),
|
||||
|
@ -302,7 +302,7 @@ impl TileTextureCache {
|
|||
}
|
||||
|
||||
pub fn has(&mut self, tile: Tile) -> bool {
|
||||
return self.grid.contains_key(&tile);
|
||||
self.grid.contains_key(&tile)
|
||||
}
|
||||
|
||||
fn remove_list(&mut self, marked: Vec<Tile>) {
|
||||
|
@ -318,7 +318,7 @@ impl TileTextureCache {
|
|||
.iter_mut()
|
||||
.filter_map(|(tile, _)| {
|
||||
if !self.visited.contains_key(tile) {
|
||||
Some(tile.clone())
|
||||
Some(*tile)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
use super::{RenderState, Shape, SurfaceId};
|
||||
use skia_safe::{self as skia, canvas::SaveLayerRec, paint, textlayout::Paragraph};
|
||||
use skia_safe::{self as skia, canvas::SaveLayerRec, textlayout::Paragraph};
|
||||
|
||||
pub fn render(
|
||||
render_state: &mut RenderState,
|
||||
shape: &Shape,
|
||||
paragraphs: &[Vec<Paragraph>],
|
||||
surface_id: Option<SurfaceId>,
|
||||
paint: Option<&paint::Paint>,
|
||||
paint: Option<skia::Paint>,
|
||||
) {
|
||||
let default_paint = skia::Paint::default();
|
||||
let mask = SaveLayerRec::default().paint(&paint.unwrap_or(&default_paint));
|
||||
let mask_paint = paint.unwrap_or_default();
|
||||
let mask = SaveLayerRec::default().paint(&mask_paint);
|
||||
let canvas = render_state
|
||||
.surfaces
|
||||
.canvas(surface_id.unwrap_or(SurfaceId::Fills));
|
||||
|
|
|
@ -74,7 +74,7 @@ impl TileHashMap {
|
|||
}
|
||||
|
||||
pub fn get_shapes_at(&mut self, tile: Tile) -> Option<&IndexSet<Uuid>> {
|
||||
return self.grid.get(&tile);
|
||||
self.grid.get(&tile)
|
||||
}
|
||||
|
||||
pub fn remove_shape_at(&mut self, tile: Tile, id: Uuid) {
|
||||
|
@ -92,13 +92,8 @@ impl TileHashMap {
|
|||
}
|
||||
|
||||
pub fn add_shape_at(&mut self, tile: Tile, shape_id: Uuid) {
|
||||
if !self.grid.contains_key(&tile) {
|
||||
self.grid.insert(tile, IndexSet::new());
|
||||
}
|
||||
|
||||
if !self.index.contains_key(&shape_id) {
|
||||
self.index.insert(shape_id, HashSet::new());
|
||||
}
|
||||
self.grid.entry(tile).or_default();
|
||||
self.index.entry(shape_id).or_default();
|
||||
|
||||
let tile_set = self.grid.get_mut(&tile).unwrap();
|
||||
tile_set.insert(shape_id);
|
||||
|
|
|
@ -224,30 +224,25 @@ impl Shape {
|
|||
}
|
||||
|
||||
pub fn has_layout(&self) -> bool {
|
||||
match self.shape_type {
|
||||
matches!(
|
||||
self.shape_type,
|
||||
Type::Frame(Frame {
|
||||
layout: Some(_), ..
|
||||
}) => true,
|
||||
_ => false,
|
||||
}
|
||||
layout: Some(_),
|
||||
..
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
pub fn set_selrect(&mut self, left: f32, top: f32, right: f32, bottom: f32) {
|
||||
self.selrect.set_ltrb(left, top, right, bottom);
|
||||
match self.shape_type {
|
||||
Type::Text(ref mut text) => {
|
||||
text.set_xywh(left, top, right - left, bottom - top);
|
||||
}
|
||||
_ => {}
|
||||
if let Type::Text(ref mut text) = self.shape_type {
|
||||
text.set_xywh(left, top, right - left, bottom - top);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_masked(&mut self, masked: bool) {
|
||||
match &mut self.shape_type {
|
||||
Type::Group(data) => {
|
||||
data.masked = masked;
|
||||
}
|
||||
_ => {}
|
||||
if let Type::Group(data) = &mut self.shape_type {
|
||||
data.masked = masked;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,7 +267,7 @@ impl Shape {
|
|||
}
|
||||
|
||||
pub fn constraint_h(&self, default: ConstraintH) -> ConstraintH {
|
||||
self.constraint_h.clone().unwrap_or(default)
|
||||
self.constraint_h.unwrap_or(default)
|
||||
}
|
||||
|
||||
pub fn set_constraint_v(&mut self, constraint: Option<ConstraintV>) {
|
||||
|
@ -280,13 +275,15 @@ impl Shape {
|
|||
}
|
||||
|
||||
pub fn constraint_v(&self, default: ConstraintV) -> ConstraintV {
|
||||
self.constraint_v.clone().unwrap_or(default)
|
||||
self.constraint_v.unwrap_or(default)
|
||||
}
|
||||
|
||||
pub fn set_hidden(&mut self, value: bool) {
|
||||
self.hidden = value;
|
||||
}
|
||||
|
||||
// FIXME: These arguments could be grouped or simplified
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn set_flex_layout_child_data(
|
||||
&mut self,
|
||||
margin_top: f32,
|
||||
|
@ -320,6 +317,8 @@ impl Shape {
|
|||
});
|
||||
}
|
||||
|
||||
// FIXME: These arguments could be grouped or simplified
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn set_flex_layout_data(
|
||||
&mut self,
|
||||
direction: FlexDirection,
|
||||
|
@ -335,32 +334,31 @@ impl Shape {
|
|||
padding_bottom: f32,
|
||||
padding_left: f32,
|
||||
) {
|
||||
match &mut self.shape_type {
|
||||
Type::Frame(data) => {
|
||||
let layout_data = LayoutData {
|
||||
align_items,
|
||||
align_content,
|
||||
justify_items,
|
||||
justify_content,
|
||||
padding_top,
|
||||
padding_right,
|
||||
padding_bottom,
|
||||
padding_left,
|
||||
row_gap,
|
||||
column_gap,
|
||||
};
|
||||
if let Type::Frame(data) = &mut self.shape_type {
|
||||
let layout_data = LayoutData {
|
||||
align_items,
|
||||
align_content,
|
||||
justify_items,
|
||||
justify_content,
|
||||
padding_top,
|
||||
padding_right,
|
||||
padding_bottom,
|
||||
padding_left,
|
||||
row_gap,
|
||||
column_gap,
|
||||
};
|
||||
|
||||
let flex_data = FlexData {
|
||||
direction,
|
||||
wrap_type,
|
||||
};
|
||||
let flex_data = FlexData {
|
||||
direction,
|
||||
wrap_type,
|
||||
};
|
||||
|
||||
data.layout = Some(Layout::FlexLayout(layout_data, flex_data));
|
||||
}
|
||||
_ => {}
|
||||
data.layout = Some(Layout::FlexLayout(layout_data, flex_data));
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: These arguments could be grouped or simplified
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn set_grid_layout_data(
|
||||
&mut self,
|
||||
direction: GridDirection,
|
||||
|
@ -375,26 +373,23 @@ impl Shape {
|
|||
padding_bottom: f32,
|
||||
padding_left: f32,
|
||||
) {
|
||||
match &mut self.shape_type {
|
||||
Type::Frame(data) => {
|
||||
let layout_data = LayoutData {
|
||||
align_items,
|
||||
align_content,
|
||||
justify_items,
|
||||
justify_content,
|
||||
padding_top,
|
||||
padding_right,
|
||||
padding_bottom,
|
||||
padding_left,
|
||||
row_gap,
|
||||
column_gap,
|
||||
};
|
||||
if let Type::Frame(data) = &mut self.shape_type {
|
||||
let layout_data = LayoutData {
|
||||
align_items,
|
||||
align_content,
|
||||
justify_items,
|
||||
justify_content,
|
||||
padding_top,
|
||||
padding_right,
|
||||
padding_bottom,
|
||||
padding_left,
|
||||
row_gap,
|
||||
column_gap,
|
||||
};
|
||||
|
||||
let mut grid_data = GridData::default();
|
||||
grid_data.direction = direction;
|
||||
data.layout = Some(Layout::GridLayout(layout_data, grid_data));
|
||||
}
|
||||
_ => {}
|
||||
let mut grid_data = GridData::default();
|
||||
grid_data.direction = direction;
|
||||
data.layout = Some(Layout::GridLayout(layout_data, grid_data));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -578,7 +573,7 @@ impl Shape {
|
|||
);
|
||||
|
||||
let center = self.center();
|
||||
let mut matrix = self.transform.clone();
|
||||
let mut matrix = self.transform;
|
||||
matrix.post_translate(center);
|
||||
matrix.pre_translate(-center);
|
||||
|
||||
|
@ -595,7 +590,7 @@ impl Shape {
|
|||
let mut rect = self.bounds().to_rect();
|
||||
for shadow in self.shadows.iter() {
|
||||
let (x, y) = shadow.offset;
|
||||
let mut shadow_rect = rect.clone();
|
||||
let mut shadow_rect = rect;
|
||||
shadow_rect.left += x;
|
||||
shadow_rect.right += x;
|
||||
shadow_rect.top += y;
|
||||
|
@ -717,12 +712,9 @@ impl Shape {
|
|||
}
|
||||
|
||||
pub fn clear_text(&mut self) {
|
||||
match &self.shape_type {
|
||||
Type::Text(old_text_content) => {
|
||||
let new_text_content = TextContent::new(self.selrect, old_text_content.grow_type());
|
||||
self.shape_type = Type::Text(new_text_content);
|
||||
}
|
||||
_ => {}
|
||||
if let Type::Text(old_text_content) = &self.shape_type {
|
||||
let new_text_content = TextContent::new(self.selrect, old_text_content.grow_type());
|
||||
self.shape_type = Type::Text(new_text_content);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -745,8 +737,8 @@ impl Shape {
|
|||
let mut center = self.selrect.center();
|
||||
center = transform.map_point(center);
|
||||
|
||||
let bounds = self.bounds().transform(&transform);
|
||||
self.transform = bounds.transform_matrix().unwrap_or(Matrix::default());
|
||||
let bounds = self.bounds().transform(transform);
|
||||
self.transform = bounds.transform_matrix().unwrap_or_default();
|
||||
|
||||
let width = bounds.width();
|
||||
let height = bounds.height();
|
||||
|
@ -761,14 +753,11 @@ impl Shape {
|
|||
}
|
||||
|
||||
pub fn apply_transform(&mut self, transform: &Matrix) {
|
||||
self.transform_selrect(&transform);
|
||||
match &mut self.shape_type {
|
||||
shape_type @ (Type::Path(_) | Type::Bool(_)) => {
|
||||
if let Some(path) = shape_type.path_mut() {
|
||||
path.transform(&transform);
|
||||
}
|
||||
self.transform_selrect(transform);
|
||||
if let shape_type @ (Type::Path(_) | Type::Bool(_)) = &mut self.shape_type {
|
||||
if let Some(path) = shape_type.path_mut() {
|
||||
path.transform(transform);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -852,7 +841,7 @@ impl Shape {
|
|||
let mut paints = Vec::new();
|
||||
|
||||
match stroke.kind {
|
||||
StrokeKind::InnerStroke => {
|
||||
StrokeKind::Inner => {
|
||||
let mut paint = skia::Paint::default();
|
||||
paint.set_blend_mode(skia::BlendMode::DstOver);
|
||||
paint.set_anti_alias(true);
|
||||
|
@ -868,7 +857,7 @@ impl Shape {
|
|||
|
||||
paints.push(paint);
|
||||
}
|
||||
StrokeKind::CenterStroke => {
|
||||
StrokeKind::Center => {
|
||||
let mut paint = skia::Paint::default();
|
||||
paint.set_style(skia::PaintStyle::Stroke);
|
||||
paint.set_anti_alias(true);
|
||||
|
@ -878,7 +867,7 @@ impl Shape {
|
|||
|
||||
paints.push(paint);
|
||||
}
|
||||
StrokeKind::OuterStroke => {
|
||||
StrokeKind::Outer => {
|
||||
let mut paint = skia::Paint::default();
|
||||
paint.set_style(skia::PaintStyle::Stroke);
|
||||
paint.set_blend_mode(skia::BlendMode::DstOver);
|
||||
|
@ -908,7 +897,7 @@ pub fn modified_children_ids(
|
|||
structure: Option<&Vec<StructureEntry>>,
|
||||
) -> IndexSet<Uuid> {
|
||||
if let Some(structure) = structure {
|
||||
let mut result: Vec<Uuid> = Vec::from_iter(element.children_ids().iter().map(|id| *id));
|
||||
let mut result: Vec<Uuid> = Vec::from_iter(element.children_ids().iter().copied());
|
||||
let mut to_remove = HashSet::<&Uuid>::new();
|
||||
|
||||
for st in structure {
|
||||
|
@ -925,7 +914,7 @@ pub fn modified_children_ids(
|
|||
let ret: IndexSet<Uuid> = result
|
||||
.iter()
|
||||
.filter(|id| !to_remove.contains(id))
|
||||
.map(|id| *id)
|
||||
.copied()
|
||||
.collect();
|
||||
|
||||
ret
|
||||
|
@ -949,7 +938,7 @@ mod tests {
|
|||
|
||||
shape.add_fill(Fill::Solid(SolidColor(Color::TRANSPARENT)));
|
||||
assert_eq!(
|
||||
shape.fills.get(0),
|
||||
shape.fills.first(),
|
||||
Some(&Fill::Solid(SolidColor(Color::TRANSPARENT)))
|
||||
)
|
||||
}
|
||||
|
@ -969,7 +958,7 @@ mod tests {
|
|||
])
|
||||
);
|
||||
} else {
|
||||
assert!(false);
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -980,9 +969,9 @@ mod tests {
|
|||
shape.set_masked(true);
|
||||
|
||||
if let Type::Group(Group { masked, .. }) = shape.shape_type {
|
||||
assert_eq!(masked, true);
|
||||
assert!(masked);
|
||||
} else {
|
||||
assert!(false);
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -312,26 +312,23 @@ pub struct FlexData {
|
|||
|
||||
impl FlexData {
|
||||
pub fn is_reverse(&self) -> bool {
|
||||
match &self.direction {
|
||||
FlexDirection::RowReverse | FlexDirection::ColumnReverse => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(
|
||||
&self.direction,
|
||||
FlexDirection::RowReverse | FlexDirection::ColumnReverse
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_row(&self) -> bool {
|
||||
match &self.direction {
|
||||
FlexDirection::RowReverse | FlexDirection::Row => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(
|
||||
&self.direction,
|
||||
FlexDirection::RowReverse | FlexDirection::Row
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FlexData {
|
||||
pub fn is_wrap(&self) -> bool {
|
||||
match self.wrap_type {
|
||||
WrapType::Wrap => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(self.wrap_type, WrapType::Wrap)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ fn propagate_children(
|
|||
) -> VecDeque<Modifier> {
|
||||
let children_ids = modified_children_ids(shape, structure.get(&shape.id));
|
||||
|
||||
if children_ids.len() == 0 || identitish(transform) {
|
||||
if children_ids.is_empty() || identitish(transform) {
|
||||
return VecDeque::new();
|
||||
}
|
||||
|
||||
|
@ -67,8 +67,8 @@ fn propagate_children(
|
|||
};
|
||||
|
||||
let transform = constraints::propagate_shape_constraints(
|
||||
&parent_bounds_before,
|
||||
&parent_bounds_after,
|
||||
parent_bounds_before,
|
||||
parent_bounds_after,
|
||||
&child_bounds,
|
||||
constraint_h,
|
||||
constraint_v,
|
||||
|
@ -87,7 +87,7 @@ fn calculate_group_bounds(
|
|||
bounds: &HashMap<Uuid, Bounds>,
|
||||
structure: &HashMap<Uuid, Vec<StructureEntry>>,
|
||||
) -> Option<Bounds> {
|
||||
let shape_bounds = bounds.find(&shape);
|
||||
let shape_bounds = bounds.find(shape);
|
||||
let mut result = Vec::<Point>::new();
|
||||
|
||||
let children_ids = modified_children_ids(shape, structure.get(&shape.id));
|
||||
|
@ -100,12 +100,12 @@ fn calculate_group_bounds(
|
|||
result.append(&mut child_bounds.points());
|
||||
}
|
||||
|
||||
shape_bounds.from_points(result)
|
||||
shape_bounds.with_points(result)
|
||||
}
|
||||
|
||||
pub fn propagate_modifiers(
|
||||
state: &State,
|
||||
modifiers: &Vec<TransformEntry>,
|
||||
modifiers: &[TransformEntry],
|
||||
) -> (Vec<TransformEntry>, HashMap<Uuid, Bounds>) {
|
||||
let shapes = &state.shapes;
|
||||
|
||||
|
@ -115,7 +115,7 @@ pub fn propagate_modifiers(
|
|||
.map(|entry| Modifier::Transform(entry.clone()))
|
||||
.collect();
|
||||
|
||||
for (id, _) in &state.structure {
|
||||
for id in state.structure.keys() {
|
||||
if id != &Uuid::nil() {
|
||||
entries.push_back(Modifier::Reflow(*id));
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ pub fn propagate_modifiers(
|
|||
continue;
|
||||
};
|
||||
|
||||
let shape_bounds_before = bounds.find(&shape);
|
||||
let shape_bounds_before = bounds.find(shape);
|
||||
let mut shape_bounds_after = shape_bounds_before.transform(&entry.transform);
|
||||
|
||||
let mut transform = entry.transform;
|
||||
|
@ -176,9 +176,7 @@ pub fn propagate_modifiers(
|
|||
|
||||
bounds.insert(shape.id, shape_bounds_after);
|
||||
|
||||
let default_matrix = Matrix::default();
|
||||
let mut shape_modif =
|
||||
modifiers.get(&shape.id).unwrap_or(&default_matrix).clone();
|
||||
let mut shape_modif = modifiers.get(&shape.id).copied().unwrap_or_default();
|
||||
shape_modif.post_concat(&transform);
|
||||
modifiers.insert(shape.id, shape_modif);
|
||||
|
||||
|
@ -230,7 +228,7 @@ pub fn propagate_modifiers(
|
|||
let children_ids =
|
||||
modified_children_ids(shape, state.structure.get(&shape.id));
|
||||
if let Some(child) = shapes.get(&children_ids[0]) {
|
||||
let child_bounds = bounds.find(&child);
|
||||
let child_bounds = bounds.find(child);
|
||||
bounds.insert(shape.id, child_bounds);
|
||||
reflow_parent = true;
|
||||
}
|
||||
|
@ -269,11 +267,11 @@ pub fn propagate_modifiers(
|
|||
}
|
||||
|
||||
for id in layout_reflows.iter() {
|
||||
if reflown.contains(&id) {
|
||||
if reflown.contains(id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(shape) = state.shapes.get(&id) else {
|
||||
let Some(shape) = state.shapes.get(id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@ pub trait GetBounds {
|
|||
|
||||
impl GetBounds for HashMap<Uuid, Bounds> {
|
||||
fn find(&self, shape: &Shape) -> Bounds {
|
||||
self.get(&shape.id)
|
||||
.map(|b| b.clone())
|
||||
.unwrap_or(shape.bounds())
|
||||
self.get(&shape.id).copied().unwrap_or(shape.bounds())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,16 +120,14 @@ pub fn propagate_shape_constraints(
|
|||
if let Some((scale_width, scale_height)) = calculate_resize(
|
||||
constraint_h,
|
||||
constraint_v,
|
||||
&parent_bounds_before,
|
||||
&parent_bounds_after,
|
||||
&child_bounds_before,
|
||||
parent_bounds_before,
|
||||
parent_bounds_after,
|
||||
child_bounds_before,
|
||||
&child_bounds_after,
|
||||
) {
|
||||
let center = child_bounds_before.center();
|
||||
|
||||
let mut parent_transform = parent_bounds_after
|
||||
.transform_matrix()
|
||||
.unwrap_or(Matrix::default());
|
||||
let mut parent_transform = parent_bounds_after.transform_matrix().unwrap_or_default();
|
||||
parent_transform.post_translate(center);
|
||||
parent_transform.pre_translate(-center);
|
||||
|
||||
|
@ -140,7 +138,7 @@ pub fn propagate_shape_constraints(
|
|||
scale.post_translate(origin);
|
||||
scale.post_concat(&parent_transform);
|
||||
scale.pre_translate(-origin);
|
||||
scale.pre_concat(&parent_transform_inv);
|
||||
scale.pre_concat(parent_transform_inv);
|
||||
|
||||
child_bounds_after.transform_mut(&scale);
|
||||
transform.post_concat(&scale);
|
||||
|
@ -150,9 +148,9 @@ pub fn propagate_shape_constraints(
|
|||
if let Some((delta_x, delta_y)) = calculate_displacement(
|
||||
constraint_h,
|
||||
constraint_v,
|
||||
&parent_bounds_before,
|
||||
&parent_bounds_after,
|
||||
&child_bounds_before,
|
||||
parent_bounds_before,
|
||||
parent_bounds_after,
|
||||
child_bounds_before,
|
||||
&child_bounds_after,
|
||||
) {
|
||||
let th = parent_bounds_after.hv(delta_x);
|
||||
|
|
|
@ -141,7 +141,7 @@ impl ChildAxis {
|
|||
is_fill_main: child.is_layout_horizontal_fill(),
|
||||
is_fill_across: child.is_layout_vertical_fill(),
|
||||
z_index: layout_item.map(|i| i.z_index).unwrap_or(0),
|
||||
bounds: child_bounds.clone(),
|
||||
bounds: *child_bounds,
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
|
@ -159,7 +159,7 @@ impl ChildAxis {
|
|||
is_fill_main: child.is_layout_vertical_fill(),
|
||||
is_fill_across: child.is_layout_horizontal_fill(),
|
||||
z_index: layout_item.map(|i| i.z_index).unwrap_or(0),
|
||||
bounds: child_bounds.clone(),
|
||||
bounds: *child_bounds,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -267,7 +267,7 @@ fn initialize_tracks(
|
|||
}
|
||||
|
||||
// Resize main axis fill
|
||||
fn distribute_fill_main_space(layout_axis: &LayoutAxis, tracks: &mut Vec<TrackData>) {
|
||||
fn distribute_fill_main_space(layout_axis: &LayoutAxis, tracks: &mut [TrackData]) {
|
||||
for track in tracks.iter_mut() {
|
||||
let mut left_space = layout_axis.main_space() - track.main_size;
|
||||
let mut to_resize_children: Vec<&mut ChildAxis> = Vec::new();
|
||||
|
@ -284,9 +284,9 @@ fn distribute_fill_main_space(layout_axis: &LayoutAxis, tracks: &mut Vec<TrackDa
|
|||
let child = &mut to_resize_children[i];
|
||||
let delta =
|
||||
f32::min(child.max_main_size, child.main_size + current) - child.main_size;
|
||||
child.main_size = child.main_size + delta;
|
||||
left_space = left_space - delta;
|
||||
track.main_size = track.main_size + delta;
|
||||
child.main_size += delta;
|
||||
left_space -= delta;
|
||||
track.main_size += delta;
|
||||
|
||||
if (child.main_size - child.max_main_size).abs() < MIN_SIZE {
|
||||
to_resize_children.remove(i);
|
||||
|
@ -296,7 +296,7 @@ fn distribute_fill_main_space(layout_axis: &LayoutAxis, tracks: &mut Vec<TrackDa
|
|||
}
|
||||
}
|
||||
|
||||
fn distribute_fill_across_space(layout_axis: &LayoutAxis, tracks: &mut Vec<TrackData>) {
|
||||
fn distribute_fill_across_space(layout_axis: &LayoutAxis, tracks: &mut [TrackData]) {
|
||||
let total_across_size = tracks.iter().map(|t| t.across_size).sum::<f32>()
|
||||
+ (tracks.len() - 1) as f32 * layout_axis.gap_across;
|
||||
let mut left_space = layout_axis.across_space() - total_across_size;
|
||||
|
@ -314,8 +314,8 @@ fn distribute_fill_across_space(layout_axis: &LayoutAxis, tracks: &mut Vec<Track
|
|||
let track = &mut to_resize_tracks[i];
|
||||
let delta =
|
||||
f32::min(track.max_across_size, track.across_size + current) - track.across_size;
|
||||
track.across_size = track.across_size + delta;
|
||||
left_space = left_space - delta;
|
||||
track.across_size += delta;
|
||||
left_space -= delta;
|
||||
|
||||
if (track.across_size - track.max_across_size).abs() < MIN_SIZE {
|
||||
to_resize_tracks.remove(i);
|
||||
|
@ -342,7 +342,7 @@ fn distribute_fill_across_space(layout_axis: &LayoutAxis, tracks: &mut Vec<Track
|
|||
|
||||
fn stretch_tracks_sizes(
|
||||
layout_axis: &LayoutAxis,
|
||||
tracks: &mut Vec<TrackData>,
|
||||
tracks: &mut [TrackData],
|
||||
total_across_size: f32,
|
||||
) {
|
||||
let total_across_size = total_across_size + (tracks.len() - 1) as f32 * layout_axis.gap_across;
|
||||
|
@ -350,7 +350,7 @@ fn stretch_tracks_sizes(
|
|||
let delta = left_space / tracks.len() as f32;
|
||||
|
||||
for track in tracks.iter_mut() {
|
||||
track.across_size = track.across_size + delta;
|
||||
track.across_size += delta;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ fn calculate_track_positions(
|
|||
layout_data: &LayoutData,
|
||||
layout_axis: &LayoutAxis,
|
||||
layout_bounds: &Bounds,
|
||||
tracks: &mut Vec<TrackData>,
|
||||
tracks: &mut [TrackData],
|
||||
total_across_size: f32,
|
||||
) {
|
||||
let mut align_content = &layout_data.align_content;
|
||||
|
@ -411,7 +411,7 @@ fn calculate_track_positions(
|
|||
|
||||
for track in tracks.iter_mut() {
|
||||
track.anchor = next_anchor;
|
||||
next_anchor = next_anchor + layout_axis.across_v * real_gap;
|
||||
next_anchor += layout_axis.across_v * real_gap;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,7 +450,7 @@ fn calculate_track_data(
|
|||
}
|
||||
|
||||
calculate_track_positions(
|
||||
&layout_data,
|
||||
layout_data,
|
||||
&layout_axis,
|
||||
layout_bounds,
|
||||
&mut tracks,
|
||||
|
@ -556,7 +556,7 @@ pub fn reflow_flex_layout(
|
|||
structure: &HashMap<Uuid, Vec<StructureEntry>>,
|
||||
) -> VecDeque<Modifier> {
|
||||
let mut result = VecDeque::new();
|
||||
let layout_bounds = &bounds.find(&shape);
|
||||
let layout_bounds = &bounds.find(shape);
|
||||
let layout_axis = LayoutAxis::new(shape, layout_bounds, layout_data, flex_data);
|
||||
let tracks = calculate_track_data(
|
||||
shape,
|
||||
|
@ -570,7 +570,7 @@ pub fn reflow_flex_layout(
|
|||
|
||||
for track in tracks.iter() {
|
||||
let total_shapes_size = track.shapes.iter().map(|s| s.main_size).sum::<f32>();
|
||||
let mut shape_anchor = first_anchor(&layout_data, &layout_axis, track, total_shapes_size);
|
||||
let mut shape_anchor = first_anchor(layout_data, &layout_axis, track, total_shapes_size);
|
||||
|
||||
for child_axis in track.shapes.iter() {
|
||||
let child_id = child_axis.id;
|
||||
|
@ -602,7 +602,7 @@ pub fn reflow_flex_layout(
|
|||
{
|
||||
transform.post_concat(&math::resize_matrix(
|
||||
layout_bounds,
|
||||
&child_bounds,
|
||||
child_bounds,
|
||||
new_width,
|
||||
new_height,
|
||||
));
|
||||
|
@ -615,10 +615,10 @@ pub fn reflow_flex_layout(
|
|||
result.push_back(Modifier::transform(child.id, transform));
|
||||
|
||||
shape_anchor = next_anchor(
|
||||
&layout_data,
|
||||
layout_data,
|
||||
&layout_axis,
|
||||
&child_axis,
|
||||
&track,
|
||||
child_axis,
|
||||
track,
|
||||
shape_anchor,
|
||||
total_shapes_size,
|
||||
);
|
||||
|
@ -681,9 +681,7 @@ pub fn reflow_flex_layout(
|
|||
)
|
||||
};
|
||||
|
||||
let parent_transform = layout_bounds
|
||||
.transform_matrix()
|
||||
.unwrap_or(Matrix::default());
|
||||
let parent_transform = layout_bounds.transform_matrix().unwrap_or_default();
|
||||
|
||||
let parent_transform_inv = &parent_transform.invert().unwrap();
|
||||
let origin = parent_transform_inv.map_point(layout_bounds.nw);
|
||||
|
@ -692,7 +690,7 @@ pub fn reflow_flex_layout(
|
|||
scale.post_translate(origin);
|
||||
scale.post_concat(&parent_transform);
|
||||
scale.pre_translate(-origin);
|
||||
scale.pre_concat(&parent_transform_inv);
|
||||
scale.pre_concat(parent_transform_inv);
|
||||
|
||||
let layout_bounds_after = layout_bounds.transform(&scale);
|
||||
result.push_back(Modifier::parent(shape.id, scale));
|
||||
|
|
|
@ -33,6 +33,8 @@ struct TrackData {
|
|||
anchor_end: Point,
|
||||
}
|
||||
|
||||
// FIXME: We might be able to simplify these arguments
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn calculate_tracks(
|
||||
is_column: bool,
|
||||
shape: &Shape,
|
||||
|
@ -61,11 +63,12 @@ fn calculate_tracks(
|
|||
set_flex_multi_span(is_column, &mut tracks, cells, shapes, bounds);
|
||||
set_fr_value(is_column, shape, layout_data, &mut tracks, layout_size);
|
||||
stretch_tracks(is_column, shape, layout_data, &mut tracks, layout_size);
|
||||
assign_anchors(is_column, layout_data, &layout_bounds, &mut tracks);
|
||||
return tracks;
|
||||
assign_anchors(is_column, layout_data, layout_bounds, &mut tracks);
|
||||
|
||||
tracks
|
||||
}
|
||||
|
||||
fn init_tracks(track: &Vec<GridTrack>, size: f32) -> Vec<TrackData> {
|
||||
fn init_tracks(track: &[GridTrack], size: f32) -> Vec<TrackData> {
|
||||
track
|
||||
.iter()
|
||||
.map(|t| {
|
||||
|
@ -103,7 +106,7 @@ fn min_size(column: bool, shape: &Shape, bounds: &HashMap<Uuid, Bounds>) -> f32
|
|||
// Go through cells to adjust auto sizes for span=1. Base is the max of its children
|
||||
fn set_auto_base_size(
|
||||
column: bool,
|
||||
tracks: &mut Vec<TrackData>,
|
||||
tracks: &mut [TrackData],
|
||||
cells: &Vec<GridCell>,
|
||||
shapes: &HashMap<Uuid, &mut Shape>,
|
||||
bounds: &HashMap<Uuid, Bounds>,
|
||||
|
@ -146,7 +149,7 @@ fn track_index(is_column: bool, c: &GridCell) -> (usize, usize) {
|
|||
}
|
||||
}
|
||||
|
||||
fn has_flex(is_column: bool, cell: &GridCell, tracks: &mut Vec<TrackData>) -> bool {
|
||||
fn has_flex(is_column: bool, cell: &GridCell, tracks: &mut [TrackData]) -> bool {
|
||||
let (start, end) = track_index(is_column, cell);
|
||||
(start..end).any(|i| tracks[i].track_type == GridTrackType::Flex)
|
||||
}
|
||||
|
@ -154,8 +157,8 @@ fn has_flex(is_column: bool, cell: &GridCell, tracks: &mut Vec<TrackData>) -> bo
|
|||
// Adjust multi-spaned cells with no flex columns
|
||||
fn set_auto_multi_span(
|
||||
column: bool,
|
||||
tracks: &mut Vec<TrackData>,
|
||||
cells: &Vec<GridCell>,
|
||||
tracks: &mut [TrackData],
|
||||
cells: &[GridCell],
|
||||
shapes: &HashMap<Uuid, &mut Shape>,
|
||||
bounds: &HashMap<Uuid, Bounds>,
|
||||
) {
|
||||
|
@ -193,11 +196,11 @@ fn set_auto_multi_span(
|
|||
let (start, end) = track_index(column, cell);
|
||||
|
||||
// Distribute the size between the tracks that already have a set value
|
||||
for i in start..end {
|
||||
dist = dist - tracks[i].size;
|
||||
for track in tracks[start..end].iter() {
|
||||
dist -= track.size;
|
||||
|
||||
if tracks[i].track_type == GridTrackType::Auto {
|
||||
num_auto = num_auto + 1;
|
||||
if track.track_type == GridTrackType::Auto {
|
||||
num_auto += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,19 +209,19 @@ fn set_auto_multi_span(
|
|||
let rest = dist / num_auto as f32;
|
||||
|
||||
// Distribute the space between auto tracks
|
||||
for i in start..end {
|
||||
if tracks[i].track_type == GridTrackType::Auto {
|
||||
for track in tracks[start..end].iter_mut() {
|
||||
if track.track_type == GridTrackType::Auto {
|
||||
// dist = dist - track[i].size;
|
||||
let new_size = if tracks[i].size + rest < tracks[i].max_size {
|
||||
tracks[i].size + rest
|
||||
let new_size = if track.size + rest < track.max_size {
|
||||
track.size + rest
|
||||
} else {
|
||||
num_auto = num_auto - 1;
|
||||
tracks[i].max_size
|
||||
num_auto -= 1;
|
||||
track.max_size
|
||||
};
|
||||
|
||||
let aloc = new_size - tracks[i].size;
|
||||
dist = dist - aloc;
|
||||
tracks[i].size = tracks[i].size + aloc;
|
||||
let aloc = new_size - track.size;
|
||||
dist -= aloc;
|
||||
track.size += aloc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -228,8 +231,8 @@ fn set_auto_multi_span(
|
|||
// Adjust multi-spaned cells with flex columns
|
||||
fn set_flex_multi_span(
|
||||
column: bool,
|
||||
tracks: &mut Vec<TrackData>,
|
||||
cells: &Vec<GridCell>,
|
||||
tracks: &mut [TrackData],
|
||||
cells: &[GridCell],
|
||||
shapes: &HashMap<Uuid, &mut Shape>,
|
||||
bounds: &HashMap<Uuid, Bounds>,
|
||||
) {
|
||||
|
@ -269,16 +272,16 @@ fn set_flex_multi_span(
|
|||
let (start, end) = track_index(column, cell);
|
||||
|
||||
// Distribute the size between the tracks that already have a set value
|
||||
for i in start..end {
|
||||
dist = dist - tracks[i].size;
|
||||
for track in tracks[start..end].iter() {
|
||||
dist -= track.size;
|
||||
|
||||
match tracks[i].track_type {
|
||||
match track.track_type {
|
||||
GridTrackType::Flex => {
|
||||
num_flex = num_flex + tracks[i].value;
|
||||
num_auto = num_auto + 1;
|
||||
num_flex += track.value;
|
||||
num_auto += 1;
|
||||
}
|
||||
GridTrackType::Auto => {
|
||||
num_auto = num_auto + 1;
|
||||
num_auto += 1;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -289,15 +292,15 @@ fn set_flex_multi_span(
|
|||
continue;
|
||||
}
|
||||
|
||||
let rest = dist / num_flex as f32;
|
||||
let rest = dist / num_flex;
|
||||
|
||||
// Distribute the space between flex tracks in proportion to the division
|
||||
for i in start..end {
|
||||
if tracks[i].track_type == GridTrackType::Flex {
|
||||
let new_size = f32::min(tracks[i].size + rest, tracks[i].max_size);
|
||||
let aloc = new_size - tracks[i].size;
|
||||
dist = dist - aloc;
|
||||
tracks[i].size = tracks[i].size + aloc;
|
||||
for track in tracks[start..end].iter_mut() {
|
||||
if track.track_type == GridTrackType::Flex {
|
||||
let new_size = f32::min(track.size + rest, track.max_size);
|
||||
let aloc = new_size - track.size;
|
||||
dist -= aloc;
|
||||
track.size += aloc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,20 +308,20 @@ fn set_flex_multi_span(
|
|||
while dist > MIN_SIZE && num_auto > 0 {
|
||||
let rest = dist / num_auto as f32;
|
||||
|
||||
for i in start..end {
|
||||
if tracks[i].track_type == GridTrackType::Auto
|
||||
|| tracks[i].track_type == GridTrackType::Flex
|
||||
for track in tracks[start..end].iter_mut() {
|
||||
if track.track_type == GridTrackType::Auto
|
||||
|| track.track_type == GridTrackType::Flex
|
||||
{
|
||||
let new_size = if tracks[i].size + rest < tracks[i].max_size {
|
||||
tracks[i].size + rest
|
||||
let new_size = if track.size + rest < track.max_size {
|
||||
track.size + rest
|
||||
} else {
|
||||
num_auto = num_auto - 1;
|
||||
tracks[i].max_size
|
||||
num_auto -= 1;
|
||||
track.max_size
|
||||
};
|
||||
|
||||
let aloc = new_size - tracks[i].size;
|
||||
dist = dist - aloc;
|
||||
tracks[i].size = tracks[i].size + aloc;
|
||||
let aloc = new_size - track.size;
|
||||
dist -= aloc;
|
||||
track.size += aloc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +333,7 @@ fn set_fr_value(
|
|||
column: bool,
|
||||
shape: &Shape,
|
||||
layout_data: &LayoutData,
|
||||
tracks: &mut Vec<TrackData>,
|
||||
tracks: &mut [TrackData],
|
||||
layout_size: f32,
|
||||
) {
|
||||
let tot_gap: f32 = if column {
|
||||
|
@ -380,7 +383,7 @@ fn stretch_tracks(
|
|||
column: bool,
|
||||
shape: &Shape,
|
||||
layout_data: &LayoutData,
|
||||
tracks: &mut Vec<TrackData>,
|
||||
tracks: &mut [TrackData],
|
||||
layout_size: f32,
|
||||
) {
|
||||
if (column
|
||||
|
@ -481,7 +484,7 @@ fn assign_anchors(
|
|||
_ => (padding_start + 0.0, gap),
|
||||
};
|
||||
|
||||
cursor = cursor + (v * real_margin);
|
||||
cursor += v * real_margin;
|
||||
|
||||
for track in tracks {
|
||||
track.anchor_start = cursor;
|
||||
|
@ -511,8 +514,8 @@ fn create_cell_data<'a>(
|
|||
children: &IndexSet<Uuid>,
|
||||
shapes: &'a HashMap<Uuid, &mut Shape>,
|
||||
cells: &Vec<GridCell>,
|
||||
column_tracks: &Vec<TrackData>,
|
||||
row_tracks: &Vec<TrackData>,
|
||||
column_tracks: &[TrackData],
|
||||
row_tracks: &[TrackData],
|
||||
) -> Vec<CellData<'a>> {
|
||||
let mut result = Vec::<CellData<'a>>::new();
|
||||
|
||||
|
@ -614,11 +617,11 @@ fn child_position(
|
|||
cell.anchor + vv * vpos + hv * hpos
|
||||
}
|
||||
|
||||
pub fn reflow_grid_layout<'a>(
|
||||
pub fn reflow_grid_layout(
|
||||
shape: &Shape,
|
||||
layout_data: &LayoutData,
|
||||
grid_data: &GridData,
|
||||
shapes: &'a HashMap<Uuid, &mut Shape>,
|
||||
shapes: &HashMap<Uuid, &mut Shape>,
|
||||
bounds: &mut HashMap<Uuid, Bounds>,
|
||||
structure: &HashMap<Uuid, Vec<StructureEntry>>,
|
||||
) -> VecDeque<Modifier> {
|
||||
|
@ -693,9 +696,9 @@ pub fn reflow_grid_layout<'a>(
|
|||
}
|
||||
|
||||
let position = child_position(
|
||||
&child,
|
||||
child,
|
||||
&layout_bounds,
|
||||
&layout_data,
|
||||
layout_data,
|
||||
&child_bounds,
|
||||
child.layout_item,
|
||||
cell,
|
||||
|
@ -733,9 +736,7 @@ pub fn reflow_grid_layout<'a>(
|
|||
scale_height = auto_height / height;
|
||||
}
|
||||
|
||||
let parent_transform = layout_bounds
|
||||
.transform_matrix()
|
||||
.unwrap_or(Matrix::default());
|
||||
let parent_transform = layout_bounds.transform_matrix().unwrap_or_default();
|
||||
|
||||
let parent_transform_inv = &parent_transform.invert().unwrap();
|
||||
let origin = parent_transform_inv.map_point(layout_bounds.nw);
|
||||
|
@ -744,7 +745,7 @@ pub fn reflow_grid_layout<'a>(
|
|||
scale.post_translate(origin);
|
||||
scale.post_concat(&parent_transform);
|
||||
scale.pre_translate(-origin);
|
||||
scale.pre_concat(&parent_transform_inv);
|
||||
scale.pre_concat(parent_transform_inv);
|
||||
|
||||
let layout_bounds_after = layout_bounds.transform(&scale);
|
||||
result.push_back(Modifier::parent(shape.id, scale));
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::array::TryFromSliceError;
|
|||
type Point = (f32, f32);
|
||||
|
||||
fn stringify_slice_err(_: TryFromSliceError) -> String {
|
||||
format!("Error deserializing path")
|
||||
"Error deserializing path".to_string()
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -89,7 +89,7 @@ impl TryFrom<Vec<RawPathData>> for Path {
|
|||
let mut open = true;
|
||||
let segments = value
|
||||
.into_iter()
|
||||
.map(|raw| Segment::try_from(raw))
|
||||
.map(Segment::try_from)
|
||||
.collect::<Result<Vec<Segment>, String>>()?;
|
||||
|
||||
let mut skia_path = skia::Path::new();
|
||||
|
|
|
@ -52,9 +52,9 @@ impl From<u8> for StrokeCap {
|
|||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum StrokeKind {
|
||||
InnerStroke,
|
||||
OuterStroke,
|
||||
CenterStroke,
|
||||
Inner,
|
||||
Outer,
|
||||
Center,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
|
@ -71,7 +71,7 @@ impl Stroke {
|
|||
// Strokes for open shapes should be rendered as if they were centered.
|
||||
pub fn render_kind(&self, is_open: bool) -> StrokeKind {
|
||||
if is_open {
|
||||
StrokeKind::CenterStroke
|
||||
StrokeKind::Center
|
||||
} else {
|
||||
self.kind
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ impl Stroke {
|
|||
style: StrokeStyle::from(style),
|
||||
cap_end: StrokeCap::from(cap_end),
|
||||
cap_start: StrokeCap::from(cap_start),
|
||||
kind: StrokeKind::CenterStroke,
|
||||
kind: StrokeKind::Center,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ impl Stroke {
|
|||
style: StrokeStyle::from(style),
|
||||
cap_end: StrokeCap::from(cap_end),
|
||||
cap_start: StrokeCap::from(cap_start),
|
||||
kind: StrokeKind::InnerStroke,
|
||||
kind: StrokeKind::Inner,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,30 +106,28 @@ impl Stroke {
|
|||
style: StrokeStyle::from(style),
|
||||
cap_end: StrokeCap::from(cap_end),
|
||||
cap_start: StrokeCap::from(cap_start),
|
||||
kind: StrokeKind::OuterStroke,
|
||||
kind: StrokeKind::Outer,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delta(&self) -> f32 {
|
||||
match self.kind {
|
||||
StrokeKind::InnerStroke => 0.,
|
||||
StrokeKind::CenterStroke => self.width,
|
||||
StrokeKind::OuterStroke => self.width * 2.,
|
||||
StrokeKind::Inner => 0.,
|
||||
StrokeKind::Center => self.width,
|
||||
StrokeKind::Outer => self.width * 2.,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn outer_rect(&self, rect: &Rect) -> Rect {
|
||||
match self.kind {
|
||||
StrokeKind::InnerStroke => Rect::from_xywh(
|
||||
StrokeKind::Inner => Rect::from_xywh(
|
||||
rect.left + (self.width / 2.),
|
||||
rect.top + (self.width / 2.),
|
||||
rect.width() - self.width,
|
||||
rect.height() - self.width,
|
||||
),
|
||||
StrokeKind::CenterStroke => {
|
||||
Rect::from_xywh(rect.left, rect.top, rect.width(), rect.height())
|
||||
}
|
||||
StrokeKind::OuterStroke => Rect::from_xywh(
|
||||
StrokeKind::Center => Rect::from_xywh(rect.left, rect.top, rect.width(), rect.height()),
|
||||
StrokeKind::Outer => Rect::from_xywh(
|
||||
rect.left - (self.width / 2.),
|
||||
rect.top - (self.width / 2.),
|
||||
rect.width() + self.width,
|
||||
|
@ -140,12 +138,12 @@ impl Stroke {
|
|||
|
||||
pub fn outer_corners(&self, corners: &Corners) -> Corners {
|
||||
let offset = match self.kind {
|
||||
StrokeKind::CenterStroke => 0.0,
|
||||
StrokeKind::InnerStroke => -self.width / 2.0,
|
||||
StrokeKind::OuterStroke => self.width / 2.0,
|
||||
StrokeKind::Center => 0.0,
|
||||
StrokeKind::Inner => -self.width / 2.0,
|
||||
StrokeKind::Outer => self.width / 2.0,
|
||||
};
|
||||
|
||||
let mut outer = corners.clone();
|
||||
let mut outer = *corners;
|
||||
for corner in outer.iter_mut() {
|
||||
corner.offset((offset, offset))
|
||||
}
|
||||
|
@ -163,9 +161,9 @@ impl Stroke {
|
|||
paint.set_style(skia::PaintStyle::Stroke);
|
||||
|
||||
let width = match self.kind {
|
||||
StrokeKind::InnerStroke => self.width,
|
||||
StrokeKind::CenterStroke => self.width,
|
||||
StrokeKind::OuterStroke => self.width + (1. / scale),
|
||||
StrokeKind::Inner => self.width,
|
||||
StrokeKind::Center => self.width,
|
||||
StrokeKind::Outer => self.width + (1. / scale),
|
||||
};
|
||||
|
||||
paint.set_stroke_width(width);
|
||||
|
@ -184,9 +182,9 @@ impl Stroke {
|
|||
StrokeStyle::Dotted => {
|
||||
let mut circle_path = skia::Path::new();
|
||||
let width = match self.kind {
|
||||
StrokeKind::InnerStroke => self.width,
|
||||
StrokeKind::CenterStroke => self.width / 2.0,
|
||||
StrokeKind::OuterStroke => self.width,
|
||||
StrokeKind::Inner => self.width,
|
||||
StrokeKind::Center => self.width / 2.0,
|
||||
StrokeKind::Outer => self.width,
|
||||
};
|
||||
circle_path.add_circle((0.0, 0.0), width, None);
|
||||
let advance = self.width + 5.0;
|
||||
|
@ -227,11 +225,11 @@ impl Stroke {
|
|||
) -> skia::Paint {
|
||||
let mut paint = self.to_paint(rect, svg_attrs, scale, antialias);
|
||||
match self.render_kind(is_open) {
|
||||
StrokeKind::InnerStroke => {
|
||||
StrokeKind::Inner => {
|
||||
paint.set_stroke_width(2. * paint.stroke_width());
|
||||
}
|
||||
StrokeKind::CenterStroke => {}
|
||||
StrokeKind::OuterStroke => {
|
||||
StrokeKind::Center => {}
|
||||
StrokeKind::Outer => {
|
||||
paint.set_stroke_width(2. * paint.stroke_width());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Default)]
|
||||
pub struct SVGRaw {
|
||||
pub content: String,
|
||||
}
|
||||
|
@ -8,11 +8,3 @@ impl SVGRaw {
|
|||
SVGRaw { content: svg }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SVGRaw {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
content: String::from(""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,10 +51,11 @@ pub fn set_paragraphs_width(width: f32, paragraphs: &mut Vec<Vec<skia::textlayou
|
|||
|
||||
impl TextContent {
|
||||
pub fn new(bounds: Rect, grow_type: GrowType) -> Self {
|
||||
let mut res = Self::default();
|
||||
res.bounds = bounds;
|
||||
res.grow_type = grow_type;
|
||||
res
|
||||
Self {
|
||||
bounds,
|
||||
grow_type,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_bounds(&self, bounds: Rect) -> Self {
|
||||
|
@ -125,7 +126,7 @@ impl TextContent {
|
|||
let paragraph_style = paragraph.paragraph_to_style();
|
||||
let mut builder = ParagraphBuilder::new(¶graph_style, fonts);
|
||||
for leaf in ¶graph.children {
|
||||
let stroke_style = leaf.to_stroke_style(paragraph, &stroke_paint);
|
||||
let stroke_style = leaf.to_stroke_style(paragraph, stroke_paint);
|
||||
let text: String = leaf.apply_text_transform(paragraph.text_transform);
|
||||
builder.push_style(&stroke_style);
|
||||
builder.add_text(&text);
|
||||
|
@ -217,6 +218,8 @@ impl Default for Paragraph {
|
|||
}
|
||||
|
||||
impl Paragraph {
|
||||
// FIXME: These arguments could be grouped or simplified
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
text_align: u8,
|
||||
text_decoration: u8,
|
||||
|
@ -542,13 +545,13 @@ impl From<&Vec<u8>> for RawTextData {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn auto_width(paragraphs: &Vec<Vec<skia::textlayout::Paragraph>>) -> f32 {
|
||||
pub fn auto_width(paragraphs: &[Vec<skia::textlayout::Paragraph>]) -> f32 {
|
||||
paragraphs.iter().flatten().fold(0.0, |auto_width, p| {
|
||||
f32::max(p.max_intrinsic_width(), auto_width)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn auto_height(paragraphs: &Vec<Vec<skia::textlayout::Paragraph>>) -> f32 {
|
||||
pub fn auto_height(paragraphs: &[Vec<skia::textlayout::Paragraph>]) -> f32 {
|
||||
paragraphs
|
||||
.iter()
|
||||
.flatten()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::collections::{hash_map::Entry, HashMap};
|
||||
|
||||
use skia_safe as skia;
|
||||
|
||||
|
@ -24,6 +24,8 @@ use crate::uuid::Uuid;
|
|||
/// state shapes attribute
|
||||
pub(crate) struct ShapesPool {
|
||||
// We need a box so that pushing here doesn't invalidate state.shapes references
|
||||
// FIXME: See if we can avoid this
|
||||
#[allow(clippy::vec_box)]
|
||||
shapes: Vec<Box<Shape>>,
|
||||
counter: usize,
|
||||
}
|
||||
|
@ -116,9 +118,9 @@ impl<'a> State<'a> {
|
|||
}
|
||||
|
||||
pub fn use_shape(&'a mut self, id: Uuid) {
|
||||
if !self.shapes.contains_key(&id) {
|
||||
if let Entry::Vacant(e) = self.shapes.entry(id) {
|
||||
let new_shape = self.shapes_pool.add_shape(id);
|
||||
self.shapes.insert(id, new_shape);
|
||||
e.insert(new_shape);
|
||||
}
|
||||
self.current_id = Some(id);
|
||||
self.current_shape = self.shapes.get_mut(&id).map(|r| &mut **r);
|
||||
|
@ -127,7 +129,7 @@ impl<'a> State<'a> {
|
|||
pub fn delete_shape(&mut self, id: Uuid) {
|
||||
// We don't really do a self.shapes.remove so that redo/undo keep working
|
||||
if let Some(shape) = self.shapes.get(&id) {
|
||||
let (rsx, rsy, rex, rey) = self.render_state.get_tiles_for_shape(&shape);
|
||||
let (rsx, rsy, rex, rey) = self.render_state.get_tiles_for_shape(shape);
|
||||
for x in rsx..=rex {
|
||||
for y in rsy..=rey {
|
||||
let tile = (x, y);
|
||||
|
@ -152,7 +154,7 @@ impl<'a> State<'a> {
|
|||
shape.set_selrect(left, top, right, bottom);
|
||||
// We don't need to update the tile for the root shape.
|
||||
if !shape.id.is_nil() {
|
||||
self.render_state.update_tile_for(&shape);
|
||||
self.render_state.update_tile_for(shape);
|
||||
}
|
||||
}
|
||||
None => panic!("Invalid current shape"),
|
||||
|
@ -165,7 +167,7 @@ impl<'a> State<'a> {
|
|||
// We don't need to update the tile for the root shape.
|
||||
// We can also have deleted the selected shape
|
||||
if !shape.id.is_nil() && self.shapes.contains_key(&shape.id) {
|
||||
self.render_state.update_tile_for(&shape);
|
||||
self.render_state.update_tile_for(shape);
|
||||
}
|
||||
}
|
||||
None => panic!("Invalid current shape"),
|
||||
|
|
|
@ -63,7 +63,7 @@ impl SerializableResult for Uuid {
|
|||
|
||||
fn as_bytes(&self) -> Self::BytesType {
|
||||
let mut result: Self::BytesType = [0; 16];
|
||||
let (a, b, c, d) = uuid_to_u32_quartet(&self);
|
||||
let (a, b, c, d) = uuid_to_u32_quartet(self);
|
||||
result[0..4].clone_from_slice(&a.to_le_bytes());
|
||||
result[4..8].clone_from_slice(&b.to_le_bytes());
|
||||
result[8..12].clone_from_slice(&c.to_le_bytes());
|
||||
|
|
|
@ -25,12 +25,13 @@ impl Default for Viewbox {
|
|||
|
||||
impl Viewbox {
|
||||
pub fn new(width: f32, height: f32) -> Self {
|
||||
let mut res = Self::default();
|
||||
res.width = width;
|
||||
res.height = height;
|
||||
res.area.set_xywh(0., 0., width, height);
|
||||
|
||||
res
|
||||
let area = Rect::from_xywh(0., 0., width, height);
|
||||
Self {
|
||||
width,
|
||||
height,
|
||||
area,
|
||||
..Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_all(&mut self, zoom: f32, pan_x: f32, pan_y: f32) {
|
||||
|
|
|
@ -24,12 +24,13 @@ macro_rules! cancel_animation_frame {
|
|||
}
|
||||
|
||||
{
|
||||
let frame_id = $frame_id;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
unsafe {
|
||||
wapi_cancelAnimationFrame($frame_id)
|
||||
wapi_cancelAnimationFrame(frame_id)
|
||||
};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let _ = $frame_id;
|
||||
let _ = frame_id;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,11 +24,8 @@ pub extern "C" fn store_font(
|
|||
.fonts_mut()
|
||||
.add(family, &font_bytes, is_emoji);
|
||||
|
||||
match res {
|
||||
Err(msg) => {
|
||||
eprintln!("{}", msg);
|
||||
}
|
||||
_ => {}
|
||||
if let Err(msg) = res {
|
||||
eprintln!("{}", msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -40,6 +37,6 @@ pub extern "C" fn is_font_uploaded(a: u32, b: u32, c: u32, d: u32, weight: u32,
|
|||
let family = FontFamily::new(id, weight, style.into());
|
||||
let res = state.render_state().fonts().has_family(&family);
|
||||
|
||||
return res;
|
||||
});
|
||||
res
|
||||
})
|
||||
}
|
||||
|
|
|
@ -49,17 +49,13 @@ pub extern "C" fn get_text_dimensions() -> *mut u8 {
|
|||
if let Type::Text(content) = &shape.shape_type {
|
||||
let paragraphs = content.get_skia_paragraphs(font_col);
|
||||
height = auto_height(¶graphs).ceil();
|
||||
match content.grow_type() {
|
||||
GrowType::AutoWidth => {
|
||||
width = auto_width(¶graphs).ceil();
|
||||
}
|
||||
_ => {}
|
||||
if content.grow_type() == GrowType::AutoWidth {
|
||||
width = auto_width(¶graphs).ceil();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mut bytes = Vec::<u8>::with_capacity(8);
|
||||
bytes.resize(8, 0);
|
||||
let mut bytes = vec![0; 8];
|
||||
bytes[0..4].clone_from_slice(&width.to_le_bytes());
|
||||
bytes[4..8].clone_from_slice(&height.to_le_bytes());
|
||||
mem::write_bytes(bytes)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue