Skip to content

Commit

Permalink
Merge pull request theyakka#1 from alexanderkind/add-rounded-corners
Browse files Browse the repository at this point in the history
add borderRadius for eyeStyle and dataModuleStyle
  • Loading branch information
alexanderkind committed Dec 2, 2022
2 parents 1fc6e38 + 955c900 commit 78729a6
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 29 deletions.
4 changes: 2 additions & 2 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 30
compileSdkVersion 33

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -39,7 +39,7 @@ android {
defaultConfig {
applicationId "app.yakka.example"
minSdkVersion 16
targetSdkVersion 30
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
1 change: 1 addition & 0 deletions example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
android:value="2" />
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
Expand Down
2 changes: 1 addition & 1 deletion example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.3.72'
ext.kotlin_version = '1.6.21'
repositories {
google()
jcenter()
Expand Down
7 changes: 5 additions & 2 deletions example/lib/main_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class _MainScreenState extends State<MainScreen> {
Widget build(BuildContext context) {
final message =
// ignore: lines_longer_than_80_chars
'Hey this is a QR code. Change this value in the main_screen.dart file.';
'12345678901234567890';

final qrFutureBuilder = FutureBuilder<ui.Image>(
future: _loadOverlayImage(),
Expand All @@ -36,13 +36,16 @@ class _MainScreenState extends State<MainScreen> {
painter: QrPainter(
data: message,
version: QrVersions.auto,
gapless: true,
eyeStyle: const QrEyeStyle(
eyeShape: QrEyeShape.square,
color: Color(0xff128760),
borderRadius: 10,
),
dataModuleStyle: const QrDataModuleStyle(
dataModuleShape: QrDataModuleShape.circle,
dataModuleShape: QrDataModuleShape.square,
color: Color(0xff1a5441),
borderRadius: 5,
),
// size: 320.0,
embeddedImage: snapshot.data,
Expand Down
87 changes: 64 additions & 23 deletions lib/src/qr_painter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;

import 'package:flutter/services.dart';
Expand Down Expand Up @@ -234,12 +233,41 @@ class QrPainter extends CustomPainter {
paintMetrics.pixelSize + pixelHTweak,
paintMetrics.pixelSize + pixelVTweak,
);
if (dataModuleStyle.dataModuleShape == QrDataModuleShape.square) {
canvas.drawRect(squareRect, paint);
} else {
final roundedRect = RRect.fromRectAndRadius(squareRect,
Radius.circular(paintMetrics.pixelSize + pixelHTweak));
canvas.drawRRect(roundedRect, paint);
switch(dataModuleStyle.dataModuleShape) {
case QrDataModuleShape.square:
if(dataModuleStyle.borderRadius > 0) {
final isDarkLeft = x > 0 ? _qrImage.isDark(y, x - 1) : false;
final isDarkTop = y > 0 ? _qrImage.isDark(y - 1, x) : false;
final isDarkRight = x < _qrImage.moduleCount - 1
? _qrImage.isDark(y, x + 1) : false;
final isDarkBottom = y < _qrImage.moduleCount - 1
? _qrImage.isDark(y + 1, x) : false;

final roundedRect = RRect.fromRectAndCorners(
squareRect,
topLeft: isDarkTop || isDarkLeft
? Radius.zero
: Radius.circular(dataModuleStyle.borderRadius),
topRight: isDarkTop || isDarkRight
? Radius.zero
: Radius.circular(dataModuleStyle.borderRadius),
bottomLeft: isDarkBottom || isDarkLeft
? Radius.zero
: Radius.circular(dataModuleStyle.borderRadius),
bottomRight: isDarkBottom || isDarkRight
? Radius.zero
: Radius.circular(dataModuleStyle.borderRadius),
);
canvas.drawRRect(roundedRect, paint);
} else {
canvas.drawRect(squareRect, paint);
}
break;
default:
final roundedRect = RRect.fromRectAndRadius(squareRect,
Radius.circular(paintMetrics.pixelSize + pixelHTweak));
canvas.drawRRect(roundedRect, paint);
break;
}
}
}
Expand Down Expand Up @@ -336,22 +364,35 @@ class QrPainter extends CustomPainter {
final dotRect = Rect.fromLTWH(offset.dx + metrics.pixelSize + strokeAdjust,
offset.dy + metrics.pixelSize + strokeAdjust, dotSize, dotSize);

if (eyeStyle.eyeShape == QrEyeShape.square) {
canvas.drawRect(outerRect, outerPaint);
canvas.drawRect(innerRect, innerPaint);
canvas.drawRect(dotRect, dotPaint);
} else {
final roundedOuterStrokeRect =
RRect.fromRectAndRadius(outerRect, Radius.circular(radius));
canvas.drawRRect(roundedOuterStrokeRect, outerPaint);

final roundedInnerStrokeRect =
RRect.fromRectAndRadius(outerRect, Radius.circular(innerRadius));
canvas.drawRRect(roundedInnerStrokeRect, innerPaint);

final roundedDotStrokeRect =
RRect.fromRectAndRadius(dotRect, Radius.circular(dotSize));
canvas.drawRRect(roundedDotStrokeRect, dotPaint);
switch(eyeStyle.eyeShape) {
case QrEyeShape.square:
if(eyeStyle.borderRadius > 0) {
final roundedOuterStrokeRect = RRect.fromRectAndRadius(
outerRect, Radius.circular(eyeStyle.borderRadius));
canvas.drawRRect(roundedOuterStrokeRect, outerPaint);
canvas.drawRect(innerRect, innerPaint);
final roundedDotStrokeRect = RRect.fromRectAndRadius(
dotRect, Radius.circular(eyeStyle.borderRadius / 2));
canvas.drawRRect(roundedDotStrokeRect, dotPaint);
} else {
canvas.drawRect(outerRect, outerPaint);
canvas.drawRect(innerRect, innerPaint);
canvas.drawRect(dotRect, dotPaint);
}
break;
default:
final roundedOuterStrokeRect =
RRect.fromRectAndRadius(outerRect, Radius.circular(radius));
canvas.drawRRect(roundedOuterStrokeRect, outerPaint);

final roundedInnerStrokeRect =
RRect.fromRectAndRadius(outerRect, Radius.circular(innerRadius));
canvas.drawRRect(roundedInnerStrokeRect, innerPaint);

final roundedDotStrokeRect =
RRect.fromRectAndRadius(dotRect, Radius.circular(dotSize));
canvas.drawRRect(roundedDotStrokeRect, dotPaint);
break;
}
}

Expand Down
9 changes: 8 additions & 1 deletion lib/src/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,17 @@ enum QrDataModuleShape {
/// Styling options for finder pattern eye.
class QrEyeStyle {
/// Create a new set of styling options for QR Eye.
const QrEyeStyle({this.eyeShape, this.color});
const QrEyeStyle({this.eyeShape, this.color, this.borderRadius = 0});

/// Eye shape.
final QrEyeShape? eyeShape;

/// Color to tint the eye.
final Color? color;

/// Border radius
final double borderRadius;

@override
int get hashCode => eyeShape.hashCode ^ color.hashCode;

Expand All @@ -87,6 +90,7 @@ class QrDataModuleStyle {
const QrDataModuleStyle({
this.dataModuleShape,
this.color,
this.borderRadius = 0,
});

/// Eye shape.
Expand All @@ -95,6 +99,9 @@ class QrDataModuleStyle {
/// Color to tint the data modules.
final Color? color;

/// Border radius
final double borderRadius;

@override
int get hashCode => dataModuleShape.hashCode ^ color.hashCode;

Expand Down

0 comments on commit 78729a6

Please sign in to comment.