mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 13:30:48 +00:00
Merge branch 'master' into construct_color
This commit is contained in:
commit
cd5e9cdfbb
5 changed files with 62 additions and 17 deletions
|
@ -143,7 +143,7 @@ impl LayoutHolder for ShapeTool {
|
|||
true,
|
||||
|_| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::FillColor(None)).into(),
|
||||
|color_type: ToolColorType| WidgetCallback::new(move |_| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::FillColorType(color_type.clone())).into()),
|
||||
|color: &ColorInput| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::FillColor(color.value.as_solid())).into(),
|
||||
|color: &ColorInput| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::FillColor(color.value.as_solid().map(|color| color.to_linear_srgb()))).into(),
|
||||
));
|
||||
|
||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
|
@ -154,7 +154,7 @@ impl LayoutHolder for ShapeTool {
|
|||
true,
|
||||
|_| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::StrokeColor(None)).into(),
|
||||
|color_type: ToolColorType| WidgetCallback::new(move |_| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::StrokeColorType(color_type.clone())).into()),
|
||||
|color: &ColorInput| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::StrokeColor(color.value.as_solid())).into(),
|
||||
|color: &ColorInput| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::StrokeColor(color.value.as_solid().map(|color| color.to_linear_srgb()))).into(),
|
||||
));
|
||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
widgets.push(create_weight_widget(self.options.line_weight));
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
let open = false;
|
||||
|
||||
$: watchSelectedIndex(selectedIndex);
|
||||
$: watchEntries(entries);
|
||||
$: watchActiveEntry(activeEntry);
|
||||
$: watchOpen(open);
|
||||
|
||||
|
@ -38,7 +39,13 @@
|
|||
}
|
||||
|
||||
// Called only when `selectedIndex` is changed from outside this component
|
||||
function watchSelectedIndex(_?: number) {
|
||||
function watchSelectedIndex(_?: typeof selectedIndex) {
|
||||
activeEntrySkipWatcher = true;
|
||||
activeEntry = makeActiveEntry();
|
||||
}
|
||||
|
||||
// Called only when `entries` is changed from outside this component
|
||||
function watchEntries(_?: typeof entries) {
|
||||
activeEntrySkipWatcher = true;
|
||||
activeEntry = makeActiveEntry();
|
||||
}
|
||||
|
|
|
@ -291,7 +291,15 @@ pub fn migrate_image_frame<'de, D: serde::Deserializer<'de>>(deserializer: D) ->
|
|||
*image_frame_table.instance_mut_iter().next().unwrap().alpha_blending = alpha_blending;
|
||||
image_frame_table
|
||||
}
|
||||
FormatVersions::ImageFrame(image_frame) => RasterDataTable::new(Raster::new_cpu(image_frame.instance_ref_iter().next().unwrap().instance.image.clone())),
|
||||
FormatVersions::ImageFrame(image_frame) => RasterDataTable::new(Raster::new_cpu(
|
||||
image_frame
|
||||
.instance_ref_iter()
|
||||
.next()
|
||||
.unwrap_or(Instances::new(ImageFrame::default()).instance_ref_iter().next().unwrap())
|
||||
.instance
|
||||
.image
|
||||
.clone(),
|
||||
)),
|
||||
FormatVersions::ImageFrameTable(image_frame_table) => RasterDataTable::new(Raster::new_cpu(image_frame_table.instance_ref_iter().next().unwrap().instance.clone())),
|
||||
FormatVersions::RasterDataTable(raster_data_table) => raster_data_table,
|
||||
})
|
||||
|
|
|
@ -57,6 +57,10 @@ impl Raster<CPU> {
|
|||
let RasterStorage::Cpu(cpu) = self.data else { unreachable!() };
|
||||
cpu
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
let data = self.data();
|
||||
data.height == 0 || data.width == 0
|
||||
}
|
||||
}
|
||||
impl Default for Raster<CPU> {
|
||||
fn default() -> Self {
|
||||
|
@ -93,6 +97,10 @@ impl Raster<GPU> {
|
|||
let RasterStorage::Gpu(gpu) = &self.data else { unreachable!() };
|
||||
gpu.clone()
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
let data = self.data();
|
||||
data.width() == 0 || data.height() == 0
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "wgpu")]
|
||||
impl Deref for Raster<GPU> {
|
||||
|
@ -104,9 +112,23 @@ impl Deref for Raster<GPU> {
|
|||
}
|
||||
pub type RasterDataTable<Storage> = Instances<Raster<Storage>>;
|
||||
|
||||
impl<S: Storage> BoundingBox for RasterDataTable<S> {
|
||||
// TODO: Make this not dupliated
|
||||
impl BoundingBox for RasterDataTable<CPU> {
|
||||
fn bounding_box(&self, transform: DAffine2, _include_stroke: bool) -> Option<[DVec2; 2]> {
|
||||
self.instance_ref_iter()
|
||||
.filter(|instance| !instance.instance.is_empty()) // Eliminate empty images
|
||||
.flat_map(|instance| {
|
||||
let transform = transform * *instance.transform;
|
||||
(transform.matrix2.determinant() != 0.).then(|| (transform * Quad::from_box([DVec2::ZERO, DVec2::ONE])).bounding_box())
|
||||
})
|
||||
.reduce(Quad::combine_bounds)
|
||||
}
|
||||
}
|
||||
|
||||
impl BoundingBox for RasterDataTable<GPU> {
|
||||
fn bounding_box(&self, transform: DAffine2, _include_stroke: bool) -> Option<[DVec2; 2]> {
|
||||
self.instance_ref_iter()
|
||||
.filter(|instance| !instance.instance.is_empty()) // Eliminate empty images
|
||||
.flat_map(|instance| {
|
||||
let transform = transform * *instance.transform;
|
||||
(transform.matrix2.determinant() != 0.).then(|| (transform * Quad::from_box([DVec2::ZERO, DVec2::ONE])).bounding_box())
|
||||
|
|
|
@ -289,19 +289,21 @@ impl GraphicElementRendered for GraphicGroupTable {
|
|||
|
||||
let mut layer = false;
|
||||
|
||||
let bounds = self
|
||||
.instance_ref_iter()
|
||||
.filter_map(|element| element.instance.bounding_box(transform, true))
|
||||
.reduce(Quad::combine_bounds);
|
||||
if let Some(bounds) = bounds {
|
||||
let blend_mode = match render_params.view_mode {
|
||||
ViewMode::Outline => peniko::Mix::Normal,
|
||||
_ => alpha_blending.blend_mode.to_peniko(),
|
||||
};
|
||||
let blend_mode = match render_params.view_mode {
|
||||
ViewMode::Outline => peniko::Mix::Normal,
|
||||
_ => alpha_blending.blend_mode.to_peniko(),
|
||||
};
|
||||
let mut bounds = None;
|
||||
|
||||
let factor = if render_params.for_mask { 1. } else { alpha_blending.fill };
|
||||
let opacity = alpha_blending.opacity * factor;
|
||||
if opacity < 1. || (render_params.view_mode != ViewMode::Outline && alpha_blending.blend_mode != BlendMode::default()) {
|
||||
let factor = if render_params.for_mask { 1. } else { alpha_blending.fill };
|
||||
let opacity = alpha_blending.opacity * factor;
|
||||
if opacity < 1. || (render_params.view_mode != ViewMode::Outline && alpha_blending.blend_mode != BlendMode::default()) {
|
||||
bounds = self
|
||||
.instance_ref_iter()
|
||||
.filter_map(|element| element.instance.bounding_box(transform, true))
|
||||
.reduce(Quad::combine_bounds);
|
||||
|
||||
if let Some(bounds) = bounds {
|
||||
scene.push_layer(
|
||||
peniko::BlendMode::new(blend_mode, peniko::Compose::SrcOver),
|
||||
opacity,
|
||||
|
@ -321,6 +323,12 @@ impl GraphicElementRendered for GraphicGroupTable {
|
|||
if !next_clips {
|
||||
mask_instance_state = None;
|
||||
}
|
||||
if !layer {
|
||||
bounds = self
|
||||
.instance_ref_iter()
|
||||
.filter_map(|element| element.instance.bounding_box(transform, true))
|
||||
.reduce(Quad::combine_bounds);
|
||||
}
|
||||
|
||||
if let Some(bounds) = bounds {
|
||||
let rect = kurbo::Rect::new(bounds[0].x, bounds[0].y, bounds[1].x, bounds[1].y);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue