engine icon indicating copy to clipboard operation
engine copied to clipboard

Implement `Paint.from(other)` for `dart:ui`.

Open matanlurey opened this issue 1 year ago • 7 comments

(Tenatively) Closes https://github.com/flutter/flutter/issues/142871.

I personally think this is a reasonable request, and we (framework authors) can make some users happy in a fairly simple way (https://github.com/flutter/flutter/issues/142871, https://github.com/flutter/flutter/issues/40497).

Some questions:

  1. Is the web implementation good enough or would we want to "ship" with an optimized impl?
  2. Can folks imagine other edge cases to test beyond correctness and deep/immutable copies?

matanlurey avatar Mar 01 '24 00:03 matanlurey

Paint is unique in that we don't have a higher level API that wraps it. Pretty much all custom painter/painting code in Flutter will directly create and manipulate paint objects. For this case in particular I don't think its unreasonable to add convienence API to it.

jonahwilliams avatar Mar 01 '24 05:03 jonahwilliams

Oh shoot I had a VM implementation and I think I just didn't add it to the PR. Next week 😄

matanlurey avatar Mar 01 '24 06:03 matanlurey

We don't have higher level APIs wrapping Rect or Offset either, and those don't have these kind of convenience constructors.

My bigger concern is what to do about some of the mutable fields on paint if we adopt this. I think that however we try to document it, it will be counterintuitive ... and I'm really not sure why we'd support this kind of API when it's so easy for a user who wants the simple case to work to do the right thing themselves.

dnfield avatar Mar 01 '24 07:03 dnfield

We do, OTOH, have Path.from, and that is documented as doing some CoW behavior.

dnfield avatar Mar 01 '24 07:03 dnfield

We clearly don't need a Rect.from or Offset.from, those are very simple classes. But Paint is a big old bag of properties. IIRC the filters objects stored on Paint are actually immutable so we don't need to deeply copy

jonahwilliams avatar Mar 01 '24 21:03 jonahwilliams

Updated with the missing code for lib/ui/painting.dart and tests.

I'll note I'm still unable to run or debug the web tests, I've reached out for help.

A convenience method makes a lot of sense here:

  1. A user that wants to copy is going to have to implement it themselves
  2. We can do better than the user, because we know the internal data structure
  3. Every field, AFAICT, is deeply immutable, so the operation is very low-complexity:
Paint.from(Paint other) {
  _data.buffer.asUint32List().setAll(0, other._data.buffer.asUint32List());
  _objects = other._objects?.toList();
}

Rect and Offset are simple immutable classes, where-as Paint is more complicated.

matanlurey avatar Mar 04 '24 17:03 matanlurey

@eyebrowsoffire Jackson, the web failure (that I can't reproduce locally) only happens on chrome-dart2wasm-skwasm-ui - is there anything about this configuration that would cause hangs?

matanlurey avatar Mar 04 '24 19:03 matanlurey

This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold.

flutter-dashboard[bot] avatar Mar 24 '24 19:03 flutter-dashboard[bot]

@eyebrowsoffire I'll need some help debugging why the WASM implementation hits an infinite loop. I setup a few minutes this Friday to pair if that's more helpful, thanks!

matanlurey avatar Mar 25 '24 18:03 matanlurey

@eyebrowsoffire I'll need some help debugging why the WASM implementation hits an infinite loop. I setup a few minutes this Friday to pair if that's more helpful, thanks!

Might be easy - @eyebrowsoffire let me know there was an issue with storkeMiterLimit not being hooked up as expected, which recently got fixed. I am re-running rebased on CI to see if true :)

matanlurey avatar Mar 29 '24 20:03 matanlurey

Yup that did it, all tests passing!

matanlurey avatar Mar 29 '24 21:03 matanlurey