flutter_svg icon indicating copy to clipboard operation
flutter_svg copied to clipboard

[Bug] Rendering regressions when upgrading from flutter_svg 1.1.6 to 2.0.7

Open androidseb opened this issue 2 years ago • 4 comments

I use a large collection of icons in my product, mostly icons listed here.

I have some golden tests to check for regressions, and when upgrading flutter_svg from 1.1.6 to 2.0.7, I noticed a few regressions that I thought might be helpful to report here. I consider these regressions bugs because the rendering elsewhere (e.g. Chrome browser, Inkscape) seems to be correct.

Regression 1

SVG file

openmoji_curly_hair

Rendering on 1.1.6 (PNG)

openmoji_curly_hair_before

Rendering on 2.0.7 (PNG)

openmoji_curly_hair_after

Regression 2

SVG file

openmoji_prayer_beads

Rendering on 1.1.6 (PNG)

openmoji_prayer_beads_before

Rendering on 2.0.7 (PNG)

openmoji_prayer_beads_after

Regression 3

SVG file

openmoji_woman_gesturing_ok

Rendering on 1.1.6 (PNG)

openmoji_woman_gesturing_before

Rendering on 2.0.7 (PNG)

openmoji_woman_gesturing_ok_after

Additional notes

It appears to be a bug in the library, but in case I'm misusing anything, here is the code I use to produce those PNG images:

  static Future<Uint8List> _svgStringToPngBytes(
    String svgStringContent,
  ) async {
    const double targetWidth = 32;
    const double targetHeight= 32;
    const double devicePixelRatio = 3;
    const double scaledTargetWidth = targetWidth * devicePixelRatio;
    const double scaledTargetHeight = targetHeight * devicePixelRatio;
    final SvgStringLoader svgStringLoader = SvgStringLoader(svgStringContent);
    final PictureInfo pictureInfo = await vg.loadPicture(svgStringLoader, null);
    final double svgWidth = pictureInfo.size.width;
    final double svgHeight = pictureInfo.size.height;
    final ui.Picture picture = pictureInfo.picture;
    final ui.PictureRecorder recorder = ui.PictureRecorder();
    final ui.Canvas canvas = Canvas(recorder, Rect.fromPoints(Offset.zero, Offset(svgWidth, svgHeight)));
    final double scaleFactor = math.min(
      scaledTargetWidth / svgWidth,
      scaledTargetHeight / svgHeight,
    );
    final double scaledSvgWidth = svgWidth * scaleFactor;
    final double scaledSvgHeight = svgHeight * scaleFactor;
    canvas.translate(
      (scaledTargetWidth - scaledSvgWidth) / 2,
      (scaledTargetHeight - scaledSvgHeight) / 2,
    );
    canvas.scale(scaleFactor, scaleFactor);
    canvas.drawPicture(picture);
    final ui.Image imgByteData = await recorder.endRecording().toImage(
          scaledTargetWidth.ceil(),
          scaledTargetHeight.ceil(),
        );
    final ByteData? bytesData = await imgByteData.toByteData(format: ui.ImageByteFormat.png);
    final Uint8List imageData = bytesData?.buffer.asUint8List() ?? Uint8List(0);
    pictureInfo.picture.dispose();
    return imageData;
  }

androidseb avatar Oct 07 '23 12:10 androidseb

sME ISSUE

fisforfaheem avatar Oct 17 '23 11:10 fisforfaheem

Is this code run via flutter test or some other method?

dnfield avatar Oct 17 '23 16:10 dnfield

@dnfield this code that produced these PNG images supplied in this issue's description was run via flutter test, but I can also confirm that the same behavior occurs on real devices, running on Android, iOS or Web.

androidseb avatar Oct 18 '23 07:10 androidseb

Just adding a quick update here, this is still an issue on the latest version of Flutter today (Flutter 3.19.5).

androidseb avatar Apr 04 '24 20:04 androidseb