Skip to content

CustomPainter allows painting outside even if canvas.clipRect(rect) called correctly #66719

@maRci002

Description

@maRci002

On Android emulator Pixel 2 (1080 * 1920; 420 dpi; API: 29) I was able to paint outside of CustomPainter's bounds which shouldn't happen because canvas.clipRect(rect) was called with the correct size.

Minimal code to reproduce:

import 'dart:ui';

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Canvas test')),
      body: Padding(
        padding: EdgeInsets.all(40.0),
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.black,
              width: 1.0,
            ),
          ),
          child: LayoutBuilder(
            builder: (BuildContext context, BoxConstraints bc) {
              final size = Size(bc.maxWidth, bc.maxHeight);
              return CustomPaint(
                painter: TestPainter(),
                size: size,
              );
            },
          ),
        ),
      ),
    );
  }
}

class TestPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final rect = Offset.zero & size;
    canvas.clipRect(rect);

    final paint = Paint();
    paint
      ..style = PaintingStyle.fill
      ..color = Colors.red;
    paint.strokeWidth = 3.0;

    var offsets = [
      Offset(rect.width - 30, rect.height / 2),
      Offset(rect.width + 30, rect.height / 2),
      Offset(rect.width + 30, rect.height / 2 + 60),
      Offset(rect.width - 30, rect.height / 2 + 60),
    ];

    canvas.drawPoints(PointMode.points, [...offsets, offsets[0]], paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return false;
  }
}

Result:
image

Result if canvas.clipRect(rect); commented out (which is correct):
image

If I change PointMode.lines to PointMode.polygon
image

If I change PointMode.lines to PointMode.polygon and comment out paint.strokeWidth = 3.0; then everything works fine, I think strokeWidth ruins the whole thing.
image

flutter doctor
[√] Flutter (Channel stable, 1.20.4, on Microsoft Windows [Version 10.0.18363.1082], locale hu-HU)
    • Flutter version 1.20.4 at C:\flutter
    • Framework revision fba99f6cf9 (11 days ago), 2020-09-14 15:32:52 -0700
    • Engine revision d1bc06f032
    • Dart version 2.9.2

[√] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
• Android SDK at C:\Users\maRci002\AppData\Local\Android\Sdk
• Platform android-30, build-tools 30.0.1
• ANDROID_HOME = C:\Users\maRci002\AppData\Local\Android\Sdk
• Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
• All Android licenses accepted.

[√] Android Studio (version 4.0)
• Android Studio at C:\Program Files\Android\Android Studio
• Flutter plugin version 49.0.2
• Dart plugin version 193.7547
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

[√] Connected device (1 available)
• Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    a: layoutSystemChrome and Framework's Layout Issuesc: regressionIt was better in the past than it is nowdependency: skiaSkia team may need to help usf: material designflutter/packages/flutter/material repository.found in release: 1.20Found to occur in 1.20frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions