Change stroke weight from ints to floats (#601)

Also rename stroke "width" to "weight" in some places. Closes #587

* Change stroke weight from ints to floats

* "miter_limit" -> "line_join_miter_limit"

* Bump file format version
This commit is contained in:
Keavon Chambers 2022-04-21 13:35:35 -07:00
parent 19d59ec6f4
commit f38289f036
10 changed files with 74 additions and 74 deletions

View File

@ -1 +1 @@
{"graphene_document":{"font_cache": {"data":{},"default":null}, "root":{"visible":true,"name":null,"data":{"Folder":{"next_assignment_id":919378319526168453,"layer_ids":[919378319526168452],"layers":[{"visible":true,"name":null,"data":{"Shape":{"path":[{"MoveTo":{"x":0.0,"y":0.0}},{"LineTo":{"x":1.0,"y":0.0}},{"LineTo":{"x":1.0,"y":1.0}},{"LineTo":{"x":0.0,"y":1.0}},"ClosePath"],"style":{"stroke":null,"fill":{"Solid":{"red":0.0,"green":0.0,"blue":0.0,"alpha":1.0}}},"render_index":1,"closed":true}},"transform":{"matrix2":[303.890625,0.0,-0.0,362.10546875],"translation":[-148.83984375,-235.8828125]},"blend_mode":"Normal","opacity":1.0}]}},"transform":{"matrix2":[1.0,0.0,0.0,1.0],"translation":[259.88359375,366.9]},"blend_mode":"Normal","opacity":1.0}},"saved_document_identifier":0,"name":"Untitled Document","layer_metadata":[[[919378319526168452],{"selected":true,"expanded":false}],[[],{"selected":false,"expanded":true}]],"layer_range_selection_reference":[919378319526168452],"movement_handler":{"pan":[-118.8,-45.60000000000001],"panning":false,"snap_tilt":false,"snap_tilt_released":false,"tilt":0.0,"tilting":false,"zoom":1.0,"zooming":false,"snap_zoom":false,"mouse_position":[0.0,0.0]},"artboard_message_handler":{"artboards_graphene_document":{"font_cache": {"data": {}}, "root":{"visible":true,"name":null,"data":{"Folder":{"next_assignment_id":0,"layer_ids":[],"layers":[]}},"transform":{"matrix2":[1.0,0.0,0.0,1.0],"translation":[259.88359375,366.9]},"blend_mode":"Normal","opacity":1.0}},"artboard_ids":[]},"properties_panel_message_handler":{"active_selection":[[919378319526168452],"Artwork"]},"overlays_visible":true,"snapping_enabled":true,"view_mode":"Normal","version":"0.0.6"}
{"graphene_document":{"font_cache": {"data":{},"default":null}, "root":{"visible":true,"name":null,"data":{"Folder":{"next_assignment_id":919378319526168453,"layer_ids":[919378319526168452],"layers":[{"visible":true,"name":null,"data":{"Shape":{"path":[{"MoveTo":{"x":0.0,"y":0.0}},{"LineTo":{"x":1.0,"y":0.0}},{"LineTo":{"x":1.0,"y":1.0}},{"LineTo":{"x":0.0,"y":1.0}},"ClosePath"],"style":{"stroke":null,"fill":{"Solid":{"red":0.0,"green":0.0,"blue":0.0,"alpha":1.0}}},"render_index":1,"closed":true}},"transform":{"matrix2":[303.890625,0.0,-0.0,362.10546875],"translation":[-148.83984375,-235.8828125]},"blend_mode":"Normal","opacity":1.0}]}},"transform":{"matrix2":[1.0,0.0,0.0,1.0],"translation":[259.88359375,366.9]},"blend_mode":"Normal","opacity":1.0}},"saved_document_identifier":0,"name":"Untitled Document","layer_metadata":[[[919378319526168452],{"selected":true,"expanded":false}],[[],{"selected":false,"expanded":true}]],"layer_range_selection_reference":[919378319526168452],"movement_handler":{"pan":[-118.8,-45.60000000000001],"panning":false,"snap_tilt":false,"snap_tilt_released":false,"tilt":0.0,"tilting":false,"zoom":1.0,"zooming":false,"snap_zoom":false,"mouse_position":[0.0,0.0]},"artboard_message_handler":{"artboards_graphene_document":{"font_cache": {"data": {}}, "root":{"visible":true,"name":null,"data":{"Folder":{"next_assignment_id":0,"layer_ids":[],"layers":[]}},"transform":{"matrix2":[1.0,0.0,0.0,1.0],"translation":[259.88359375,366.9]},"blend_mode":"Normal","opacity":1.0}},"artboard_ids":[]},"properties_panel_message_handler":{"active_selection":[[919378319526168452],"Artwork"]},"overlays_visible":true,"snapping_enabled":true,"view_mode":"Normal","version":"0.0.7"}

View File

@ -57,5 +57,5 @@ pub const FILE_EXPORT_SUFFIX: &str = ".svg";
pub const COLOR_ACCENT: Color = Color::from_unsafe(0x00 as f32 / 255., 0xA8 as f32 / 255., 0xFF as f32 / 255.);
// Document
pub const GRAPHITE_DOCUMENT_VERSION: &str = "0.0.6";
pub const GRAPHITE_DOCUMENT_VERSION: &str = "0.0.7";
pub const VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR: f32 = 1.05;

View File

@ -952,13 +952,13 @@ fn node_section_stroke(stroke: &Stroke) -> LayoutRow {
direction: SeparatorDirection::Horizontal,
})),
WidgetHolder::new(Widget::NumberInput(NumberInput {
value: stroke.width() as f64,
is_integer: true,
value: stroke.weight() as f64,
is_integer: false,
min: Some(0.),
unit: " px".into(),
on_update: WidgetCallback::new(move |number_input: &NumberInput| {
PropertiesPanelMessage::ModifyStroke {
stroke: internal_stroke2.clone().with_width(number_input.value as f32),
stroke: internal_stroke2.clone().with_weight(number_input.value),
}
.into()
}),
@ -1004,7 +1004,7 @@ fn node_section_stroke(stroke: &Stroke) -> LayoutRow {
unit: " px".into(),
on_update: WidgetCallback::new(move |number_input: &NumberInput| {
PropertiesPanelMessage::ModifyStroke {
stroke: internal_stroke4.clone().with_dash_offset(number_input.value as f32),
stroke: internal_stroke4.clone().with_dash_offset(number_input.value),
}
.into()
}),
@ -1118,13 +1118,13 @@ fn node_section_stroke(stroke: &Stroke) -> LayoutRow {
direction: SeparatorDirection::Horizontal,
})),
WidgetHolder::new(Widget::NumberInput(NumberInput {
value: stroke.miter_limit() as f64,
value: stroke.line_join_miter_limit() as f64,
is_integer: true,
min: Some(0.),
unit: "".into(),
on_update: WidgetCallback::new(move |number_input: &NumberInput| {
PropertiesPanelMessage::ModifyStroke {
stroke: internal_stroke5.clone().with_miter_limit(number_input.value as f32),
stroke: internal_stroke5.clone().with_line_join_miter_limit(number_input.value),
}
.into()
}),

View File

@ -21,18 +21,18 @@ pub struct FreehandTool {
}
pub struct FreehandOptions {
line_weight: u32,
line_weight: f64,
}
impl Default for FreehandOptions {
fn default() -> Self {
Self { line_weight: 5 }
Self { line_weight: 5. }
}
}
#[remain::sorted]
#[impl_message(Message, ToolMessage, Freehand)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum FreehandToolMessage {
// Standard messages
#[remain::unsorted]
@ -46,9 +46,9 @@ pub enum FreehandToolMessage {
}
#[remain::sorted]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum FreehandToolMessageOptionsUpdate {
LineWeight(u32),
LineWeight(f64),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@ -64,9 +64,9 @@ impl PropertyHolder for FreehandTool {
unit: " px".into(),
label: "Weight".into(),
value: self.options.line_weight as f64,
is_integer: true,
is_integer: false,
min: Some(1.),
on_update: WidgetCallback::new(|number_input: &NumberInput| FreehandToolMessage::UpdateOptions(FreehandToolMessageOptionsUpdate::LineWeight(number_input.value as u32)).into()),
on_update: WidgetCallback::new(|number_input: &NumberInput| FreehandToolMessage::UpdateOptions(FreehandToolMessageOptionsUpdate::LineWeight(number_input.value)).into()),
..NumberInput::default()
}))],
}])
@ -119,7 +119,7 @@ impl Default for FreehandToolFsmState {
#[derive(Clone, Debug, Default)]
struct FreehandToolData {
points: Vec<DVec2>,
weight: u32,
weight: f64,
path: Option<Vec<LayerId>>,
}
@ -224,7 +224,7 @@ fn add_polyline(data: &FreehandToolData, tool_data: &DocumentToolData) -> Messag
insert_index: -1,
transform: DAffine2::IDENTITY.to_cols_array(),
points,
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, data.weight as f32)), style::Fill::None),
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, data.weight)), style::Fill::None),
}
.into()
}

View File

@ -24,18 +24,18 @@ pub struct LineTool {
}
pub struct LineOptions {
line_weight: u32,
line_weight: f64,
}
impl Default for LineOptions {
fn default() -> Self {
Self { line_weight: 5 }
Self { line_weight: 5. }
}
}
#[remain::sorted]
#[impl_message(Message, ToolMessage, Line)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum LineToolMessage {
// Standard messages
#[remain::unsorted]
@ -53,9 +53,9 @@ pub enum LineToolMessage {
}
#[remain::sorted]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum LineOptionsUpdate {
LineWeight(u32),
LineWeight(f64),
}
impl PropertyHolder for LineTool {
@ -65,9 +65,9 @@ impl PropertyHolder for LineTool {
unit: " px".into(),
label: "Weight".into(),
value: self.options.line_weight as f64,
is_integer: true,
is_integer: false,
min: Some(0.),
on_update: WidgetCallback::new(|number_input: &NumberInput| LineToolMessage::UpdateOptions(LineOptionsUpdate::LineWeight(number_input.value as u32)).into()),
on_update: WidgetCallback::new(|number_input: &NumberInput| LineToolMessage::UpdateOptions(LineOptionsUpdate::LineWeight(number_input.value)).into()),
..NumberInput::default()
}))],
}])
@ -129,7 +129,7 @@ struct LineToolData {
drag_start: ViewportPosition,
drag_current: ViewportPosition,
angle: f64,
weight: u32,
weight: f64,
path: Option<Vec<LayerId>>,
snap_handler: SnapHandler,
}
@ -168,7 +168,7 @@ impl Fsm for LineToolFsmState {
path: data.path.clone().unwrap(),
insert_index: -1,
transform: DAffine2::ZERO.to_cols_array(),
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, data.weight as f32)), style::Fill::None),
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, data.weight)), style::Fill::None),
}
.into(),
);

View File

@ -27,18 +27,18 @@ pub struct PenTool {
}
pub struct PenOptions {
line_weight: u32,
line_weight: f64,
}
impl Default for PenOptions {
fn default() -> Self {
Self { line_weight: 5 }
Self { line_weight: 5. }
}
}
#[remain::sorted]
#[impl_message(Message, ToolMessage, Pen)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum PenToolMessage {
// Standard messages
#[remain::unsorted]
@ -62,9 +62,9 @@ enum PenToolFsmState {
}
#[remain::sorted]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum PenOptionsUpdate {
LineWeight(u32),
LineWeight(f64),
}
impl PropertyHolder for PenTool {
@ -73,10 +73,10 @@ impl PropertyHolder for PenTool {
widgets: vec![WidgetHolder::new(Widget::NumberInput(NumberInput {
unit: " px".into(),
label: "Weight".into(),
value: self.options.line_weight as f64,
is_integer: true,
value: self.options.line_weight,
is_integer: false,
min: Some(0.),
on_update: WidgetCallback::new(|number_input: &NumberInput| PenToolMessage::UpdateOptions(PenOptionsUpdate::LineWeight(number_input.value as u32)).into()),
on_update: WidgetCallback::new(|number_input: &NumberInput| PenToolMessage::UpdateOptions(PenOptionsUpdate::LineWeight(number_input.value)).into()),
..NumberInput::default()
}))],
}])
@ -128,7 +128,7 @@ impl Default for PenToolFsmState {
}
#[derive(Clone, Debug, Default)]
struct PenToolData {
weight: u32,
weight: f64,
path: Option<Vec<LayerId>>,
curve_shape: VectorShape,
bez_path: Vec<PathEl>,
@ -184,7 +184,7 @@ impl Fsm for PenToolFsmState {
transform: transform.to_cols_array(),
insert_index: -1,
bez_path: data.bez_path.clone().into_iter().collect(),
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, data.weight as f32)), style::Fill::None),
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, data.weight)), style::Fill::None),
closed: false,
}
.into(),

View File

@ -23,18 +23,18 @@ pub struct SplineTool {
}
pub struct SplineOptions {
line_weight: u32,
line_weight: f64,
}
impl Default for SplineOptions {
fn default() -> Self {
Self { line_weight: 5 }
Self { line_weight: 5. }
}
}
#[remain::sorted]
#[impl_message(Message, ToolMessage, Spline)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum SplineToolMessage {
// Standard messages
#[remain::unsorted]
@ -56,9 +56,9 @@ enum SplineToolFsmState {
}
#[remain::sorted]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum SplineOptionsUpdate {
LineWeight(u32),
LineWeight(f64),
}
impl PropertyHolder for SplineTool {
@ -67,10 +67,10 @@ impl PropertyHolder for SplineTool {
widgets: vec![WidgetHolder::new(Widget::NumberInput(NumberInput {
unit: " px".into(),
label: "Weight".into(),
value: self.options.line_weight as f64,
is_integer: true,
value: self.options.line_weight,
is_integer: false,
min: Some(0.),
on_update: WidgetCallback::new(|number_input: &NumberInput| SplineToolMessage::UpdateOptions(SplineOptionsUpdate::LineWeight(number_input.value as u32)).into()),
on_update: WidgetCallback::new(|number_input: &NumberInput| SplineToolMessage::UpdateOptions(SplineOptionsUpdate::LineWeight(number_input.value)).into()),
..NumberInput::default()
}))],
}])
@ -124,7 +124,7 @@ impl Default for SplineToolFsmState {
struct SplineToolData {
points: Vec<DVec2>,
next_point: DVec2,
weight: u32,
weight: f64,
path: Option<Vec<LayerId>>,
snap_handler: SnapHandler,
}
@ -265,7 +265,7 @@ fn add_spline(data: &SplineToolData, tool_data: &DocumentToolData, show_preview:
insert_index: -1,
transform: DAffine2::IDENTITY.to_cols_array(),
points,
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, data.weight as f32)), style::Fill::None),
style: style::PathStyle::new(Some(style::Stroke::new(tool_data.primary_color, data.weight)), style::Fill::None),
}
.into()
}

View File

@ -43,27 +43,27 @@ impl Default for VectorControlPoint {
}
}
const POINT_STROKE_WIDTH: f32 = 2.0;
const POINT_STROKE_WEIGHT: f64 = 2.;
impl VectorControlPoint {
/// Sets if this point is selected and updates the overlay to represent that
pub fn set_selected(&mut self, selected: bool, responses: &mut VecDeque<Message>) {
if selected {
self.set_overlay_style(POINT_STROKE_WIDTH + 1.0, COLOR_ACCENT, COLOR_ACCENT, responses);
self.set_overlay_style(POINT_STROKE_WEIGHT + 1., COLOR_ACCENT, COLOR_ACCENT, responses);
} else {
self.set_overlay_style(POINT_STROKE_WIDTH, COLOR_ACCENT, Color::WHITE, responses);
self.set_overlay_style(POINT_STROKE_WEIGHT, COLOR_ACCENT, Color::WHITE, responses);
}
self.is_selected = selected;
}
/// Sets the overlay style for this point
pub fn set_overlay_style(&self, stroke_width: f32, stroke_color: Color, fill_color: Color, responses: &mut VecDeque<Message>) {
pub fn set_overlay_style(&self, stroke_weight: f64, stroke_color: Color, fill_color: Color, responses: &mut VecDeque<Message>) {
if let Some(overlay_path) = &self.overlay_path {
responses.push_back(
DocumentMessage::Overlays(
Operation::SetLayerStyle {
path: overlay_path.clone(),
style: PathStyle::new(Some(Stroke::new(stroke_color, stroke_width)), Fill::solid(fill_color)),
style: PathStyle::new(Some(Stroke::new(stroke_color, stroke_weight)), Fill::solid(fill_color)),
}
.into(),
)

View File

@ -2,7 +2,7 @@ use crate::color::Color;
// RENDERING
pub const LAYER_OUTLINE_STROKE_COLOR: Color = Color::BLACK;
pub const LAYER_OUTLINE_STROKE_WIDTH: f32 = 1.;
pub const LAYER_OUTLINE_STROKE_WEIGHT: f64 = 1.;
// BOOLEAN OPERATIONS

View File

@ -1,7 +1,7 @@
//! Contains stylistic options for SVG elements.
use crate::color::Color;
use crate::consts::{LAYER_OUTLINE_STROKE_COLOR, LAYER_OUTLINE_STROKE_WIDTH};
use crate::consts::{LAYER_OUTLINE_STROKE_COLOR, LAYER_OUTLINE_STROKE_WEIGHT};
use glam::{DAffine2, DVec2};
use serde::{Deserialize, Serialize};
@ -188,19 +188,19 @@ pub struct Stroke {
/// Stroke color
color: Option<Color>,
/// Line thickness
width: f32,
weight: f64,
dash_lengths: Vec<f32>,
dash_offset: f32,
dash_offset: f64,
line_cap: LineCap,
line_join: LineJoin,
miter_limit: f32,
line_join_miter_limit: f64,
}
impl Stroke {
pub fn new(color: Color, width: f32) -> Self {
pub fn new(color: Color, weight: f64) -> Self {
Self {
color: Some(color),
width,
weight,
..Default::default()
}
}
@ -210,16 +210,16 @@ impl Stroke {
self.color
}
/// Get the current stroke width.
pub fn width(&self) -> f32 {
self.width
/// Get the current stroke weight.
pub fn weight(&self) -> f64 {
self.weight
}
pub fn dash_lengths(&self) -> String {
self.dash_lengths.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", ")
}
pub fn dash_offset(&self) -> f32 {
pub fn dash_offset(&self) -> f64 {
self.dash_offset
}
@ -231,8 +231,8 @@ impl Stroke {
self.line_join as u32
}
pub fn miter_limit(&self) -> f32 {
self.miter_limit as f32
pub fn line_join_miter_limit(&self) -> f32 {
self.line_join_miter_limit as f32
}
/// Provide the SVG attributes for the stroke.
@ -242,12 +242,12 @@ impl Stroke {
r##" stroke="#{}"{} stroke-width="{}" stroke-dasharray="{}" stroke-dashoffset="{}" stroke-linecap="{}" stroke-linejoin="{}" stroke-miterlimit="{}" "##,
color.rgb_hex(),
format_opacity("stroke", color.a()),
self.width,
self.weight,
self.dash_lengths(),
self.dash_offset,
self.line_cap,
self.line_join,
self.miter_limit
self.line_join_miter_limit
)
} else {
String::new()
@ -266,8 +266,8 @@ impl Stroke {
}
}
pub fn with_width(mut self, width: f32) -> Self {
self.width = width;
pub fn with_weight(mut self, weight: f64) -> Self {
self.weight = weight;
self
}
@ -284,7 +284,7 @@ impl Stroke {
})
}
pub fn with_dash_offset(mut self, dash_offset: f32) -> Self {
pub fn with_dash_offset(mut self, dash_offset: f64) -> Self {
self.dash_offset = dash_offset;
self
}
@ -299,8 +299,8 @@ impl Stroke {
self
}
pub fn with_miter_limit(mut self, miter_limit: f32) -> Self {
self.miter_limit = miter_limit;
pub fn with_line_join_miter_limit(mut self, limit: f64) -> Self {
self.line_join_miter_limit = limit;
self
}
}
@ -309,13 +309,13 @@ impl Stroke {
impl Default for Stroke {
fn default() -> Self {
Self {
width: 0.,
weight: 0.,
color: Some(Color::from_rgba8(0, 0, 0, 255)),
dash_lengths: vec![0.],
dash_offset: 0.,
line_cap: LineCap::Butt,
line_join: LineJoin::Miter,
miter_limit: 4.,
line_join_miter_limit: 4.,
}
}
}
@ -442,7 +442,7 @@ impl PathStyle {
(_, fill) => fill.render(svg_defs, multiplied_transform, bounds, transformed_bounds),
};
let stroke_attribute = match (view_mode, &self.stroke) {
(ViewMode::Outline, _) => Stroke::new(LAYER_OUTLINE_STROKE_COLOR, LAYER_OUTLINE_STROKE_WIDTH).render(),
(ViewMode::Outline, _) => Stroke::new(LAYER_OUTLINE_STROKE_COLOR, LAYER_OUTLINE_STROKE_WEIGHT).render(),
(_, Some(stroke)) => stroke.render(),
(_, None) => String::new(),
};