Found by review during #94, but pre-existing — the behaviour is unchanged by that PR, so it was filed rather than folded into a rendering rung.
What
convert_paint in crates/grida_editor/src/ui/bind.rs folds the source paint's opacity into the first stop's alpha when converting to a solid (kind 0).
For a source that is already Paint::Solid, both inputs are the same number:
paint_stops(paint) for Paint::Solid returns a first stop whose colour is p.color, alpha included.
SolidPaint::opacity() returns self.color.a() as f32 / 255.0.
So first_color.a() * opacity squares the alpha. A 50%-opaque solid converted to a solid becomes ~25% opaque.
FillKind and StrokeKind can both reach convert_paint with index 0 while the paint is already solid.
Suggested shape
Return paint.clone() when the source is already Paint::Solid and the target kind is solid, before the alpha fold; keep the existing fold for gradient and image sources, where the two numbers are genuinely independent.
Needs a test in crates/grida_editor/tests/paint_contracts.rs alongside the existing fill_kind_converts_carrying_the_color, which only covers an opaque colour and so cannot see this.
Found by review during #94, but pre-existing — the behaviour is unchanged by that PR, so it was filed rather than folded into a rendering rung.
What
convert_paintincrates/grida_editor/src/ui/bind.rsfolds the source paint's opacity into the first stop's alpha when converting to a solid (kind0).For a source that is already
Paint::Solid, both inputs are the same number:paint_stops(paint)forPaint::Solidreturns a first stop whose colour isp.color, alpha included.SolidPaint::opacity()returnsself.color.a() as f32 / 255.0.So
first_color.a() * opacitysquares the alpha. A 50%-opaque solid converted to a solid becomes ~25% opaque.FillKindandStrokeKindcan both reachconvert_paintwith index0while the paint is already solid.Suggested shape
Return
paint.clone()when the source is alreadyPaint::Solidand the target kind is solid, before the alpha fold; keep the existing fold for gradient and image sources, where the two numbers are genuinely independent.Needs a test in
crates/grida_editor/tests/paint_contracts.rsalongside the existingfill_kind_converts_carrying_the_color, which only covers an opaque colour and so cannot see this.