From fb66274bf729cde6f7184ec6f7f9ea89f12450fd Mon Sep 17 00:00:00 2001 From: otsmr Date: Mon, 8 Dec 2025 00:06:11 +0100 Subject: [PATCH] add new dependency --- config.lock.yaml | 1 + config.yaml | 7 +- pubspec.yaml | 2 + qr_flutter/LICENSE | 29 + qr_flutter/lib/qr_flutter.dart | 14 + qr_flutter/lib/src/errors.dart | 48 ++ qr_flutter/lib/src/paint_cache.dart | 55 ++ qr_flutter/lib/src/qr_image_view.dart | 336 +++++++++ qr_flutter/lib/src/qr_painter.dart | 694 ++++++++++++++++++ qr_flutter/lib/src/qr_versions.dart | 23 + qr_flutter/lib/src/types.dart | 208 ++++++ qr_flutter/lib/src/validator.dart | 80 ++ qr_flutter/pubspec.lock | 197 +++++ qr_flutter/pubspec.yaml | 22 + .../qr_image_data_module_styled_golden.png | Bin 0 -> 32358 bytes ...qr_image_eye_data_module_styled_golden.png | Bin 0 -> 41232 bytes .../.golden/qr_image_eye_styled_golden.png | Bin 0 -> 15879 bytes .../qr_image_foreground_colored_golden.png | Bin 0 -> 41271 bytes qr_flutter/test/.golden/qr_image_golden.png | Bin 0 -> 5035 bytes .../test/.golden/qr_image_logo_golden.png | Bin 0 -> 12850 bytes qr_flutter/test/.golden/qr_painter_golden.png | Bin 0 -> 1505 bytes qr_flutter/test/.images/logo_yakka.png | Bin 0 -> 8424 bytes qr_flutter/test/all_test.dart | 14 + qr_flutter/test/image_test.dart | 218 ++++++ qr_flutter/test/painter_test.dart | 41 ++ 25 files changed, 1987 insertions(+), 2 deletions(-) create mode 100644 qr_flutter/LICENSE create mode 100644 qr_flutter/lib/qr_flutter.dart create mode 100644 qr_flutter/lib/src/errors.dart create mode 100644 qr_flutter/lib/src/paint_cache.dart create mode 100644 qr_flutter/lib/src/qr_image_view.dart create mode 100644 qr_flutter/lib/src/qr_painter.dart create mode 100644 qr_flutter/lib/src/qr_versions.dart create mode 100644 qr_flutter/lib/src/types.dart create mode 100644 qr_flutter/lib/src/validator.dart create mode 100644 qr_flutter/pubspec.lock create mode 100644 qr_flutter/pubspec.yaml create mode 100644 qr_flutter/test/.golden/qr_image_data_module_styled_golden.png create mode 100644 qr_flutter/test/.golden/qr_image_eye_data_module_styled_golden.png create mode 100644 qr_flutter/test/.golden/qr_image_eye_styled_golden.png create mode 100644 qr_flutter/test/.golden/qr_image_foreground_colored_golden.png create mode 100644 qr_flutter/test/.golden/qr_image_golden.png create mode 100644 qr_flutter/test/.golden/qr_image_logo_golden.png create mode 100644 qr_flutter/test/.golden/qr_painter_golden.png create mode 100644 qr_flutter/test/.images/logo_yakka.png create mode 100644 qr_flutter/test/all_test.dart create mode 100644 qr_flutter/test/image_test.dart create mode 100644 qr_flutter/test/painter_test.dart diff --git a/config.lock.yaml b/config.lock.yaml index 5dd4b2d..9274ef1 100644 --- a/config.lock.yaml +++ b/config.lock.yaml @@ -11,4 +11,5 @@ optional: 71c638891ce4f2aff35c7387727989f31f9d877d photo_view: a13ca2fc387a3fb1276126959e092c44d0029987 pointycastle: bbd8569f68a7fccbdf0b92d0b44a9219c126c8dd qr: ff808bb3f354e6a7029ec953cbe0144a42021db6 +qr_flutter: d5e7206396105d643113618290bbcc755d05f492 x25519: ecb1d357714537bba6e276ef45f093846d4beaee diff --git a/config.yaml b/config.yaml index 787f666..6b2df32 100644 --- a/config.yaml +++ b/config.yaml @@ -1,5 +1,8 @@ -qr: - git: https://github.com/kevmoo/qr.dart.git +qr_flutter: + git: https://github.com/theyakka/qr.flutter.git + dependencies: + qr: + git: https://github.com/kevmoo/qr.dart.git mutex: git: https://github.com/hoylen/dart-mutex.git diff --git a/pubspec.yaml b/pubspec.yaml index 450a64f..144765b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,5 +25,7 @@ dependency_overrides: path: ./dependencies/pointycastle qr: path: ./dependencies/qr + qr_flutter: + path: ./dependencies/qr_flutter x25519: path: ./dependencies/x25519 diff --git a/qr_flutter/LICENSE b/qr_flutter/LICENSE new file mode 100644 index 0000000..172ec64 --- /dev/null +++ b/qr_flutter/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, Luke Freeman. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/qr_flutter/lib/qr_flutter.dart b/qr_flutter/lib/qr_flutter.dart new file mode 100644 index 0000000..6be9df6 --- /dev/null +++ b/qr_flutter/lib/qr_flutter.dart @@ -0,0 +1,14 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +export 'package:qr/qr.dart'; + +export 'src/errors.dart'; +export 'src/qr_image_view.dart'; +export 'src/qr_painter.dart'; +export 'src/qr_versions.dart'; +export 'src/types.dart'; +export 'src/validator.dart'; diff --git a/qr_flutter/lib/src/errors.dart b/qr_flutter/lib/src/errors.dart new file mode 100644 index 0000000..239b9ea --- /dev/null +++ b/qr_flutter/lib/src/errors.dart @@ -0,0 +1,48 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +import 'package:flutter/widgets.dart'; + +import 'qr_versions.dart'; + +/// An exception that is thrown when an invalid QR code version / type is +/// requested. +class QrUnsupportedVersionException implements Exception { + /// Create a new QrUnsupportedVersionException. + factory QrUnsupportedVersionException(int providedVersion) { + final message = + 'Invalid version. $providedVersion is not >= ${QrVersions.min} ' + 'and <= ${QrVersions.max}'; + return QrUnsupportedVersionException._internal(providedVersion, message); + } + + QrUnsupportedVersionException._internal(this.providedVersion, this.message); + + /// The version you passed to the QR code operation. + final int providedVersion; + + /// A message describing the exception state. + final String message; + + @override + String toString() => 'QrUnsupportedVersionException: $message'; +} + +/// An exception that is thrown when something goes wrong with the +/// [ImageProvider] for the embedded image of a QrImageView or QrPainter. +class QrEmbeddedImageException implements Exception { + /// Create a new QrEmbeddedImageException. + factory QrEmbeddedImageException(String message) { + return QrEmbeddedImageException._internal(message); + } + QrEmbeddedImageException._internal(this.message); + + /// A message describing the exception state. + final String message; + + @override + String toString() => 'QrEmbeddedImageException: $message'; +} diff --git a/qr_flutter/lib/src/paint_cache.dart b/qr_flutter/lib/src/paint_cache.dart new file mode 100644 index 0000000..ead3df3 --- /dev/null +++ b/qr_flutter/lib/src/paint_cache.dart @@ -0,0 +1,55 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +import 'package:flutter/widgets.dart'; + +import 'types.dart'; + +/// Caches painter objects so we do have to recreate them and waste expensive +/// cycles. +class PaintCache { + final List _pixelPaints = []; + final Map _keyedPaints = {}; + + String _cacheKey(QrCodeElement element, {FinderPatternPosition? position}) { + final posKey = position != null ? position.toString() : 'any'; + return '$element:$posKey'; + } + + /// Save a [Paint] for the provided element and position into the cache. + void cache( + Paint paint, + QrCodeElement element, { + FinderPatternPosition? position, + }) { + if (element == QrCodeElement.codePixel) { + _pixelPaints.add(paint); + } else { + _keyedPaints[_cacheKey(element, position: position)] = paint; + } + } + + /// Retrieve the first [Paint] object from the paint cache for the provided + /// element and position. + Paint? firstPaint(QrCodeElement element, {FinderPatternPosition? position}) { + return element == QrCodeElement.codePixel + ? _pixelPaints.first + : _keyedPaints[_cacheKey(element, position: position)]; + } + + /// Retrieve all [Paint] objects from the paint cache for the provided + /// element and position. Note: Finder pattern elements can only have a max + /// one [Paint] object per position. As such they will always return a [List] + /// with a fixed size of `1`. + List paints( + QrCodeElement element, { + FinderPatternPosition? position, + }) { + return element == QrCodeElement.codePixel + ? _pixelPaints + : [_keyedPaints[_cacheKey(element, position: position)]]; + } +} diff --git a/qr_flutter/lib/src/qr_image_view.dart b/qr_flutter/lib/src/qr_image_view.dart new file mode 100644 index 0000000..357d6ca --- /dev/null +++ b/qr_flutter/lib/src/qr_image_view.dart @@ -0,0 +1,336 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +import 'dart:async'; +import 'dart:ui' as ui; + +import 'package:flutter/material.dart'; +import 'package:qr/qr.dart'; + +import 'qr_painter.dart'; +import 'qr_versions.dart'; +import 'types.dart'; +import 'validator.dart'; + +/// A widget that shows a QR code. +class QrImageView extends StatefulWidget { + /// Create a new QR code using the [String] data and the passed options (or + /// using the default options). + QrImageView({ + required String data, + super.key, + this.size, + this.padding = const EdgeInsets.all(10.0), + this.backgroundColor = Colors.transparent, + @Deprecated('use colors in eyeStyle and dataModuleStyle instead') + this.foregroundColor = Colors.black, + this.version = QrVersions.auto, + this.errorCorrectionLevel = QrErrorCorrectLevel.L, + this.errorStateBuilder, + this.constrainErrorBounds = true, + this.gapless = true, + this.embeddedImage, + this.embeddedImageStyle = const QrEmbeddedImageStyle(), + this.semanticsLabel = 'qr code', + this.eyeStyle = const QrEyeStyle( + eyeShape: QrEyeShape.square, + ), + this.dataModuleStyle = const QrDataModuleStyle( + dataModuleShape: QrDataModuleShape.square, + ), + this.embeddedImageEmitsError = false, + this.gradient, + }) : assert( + QrVersions.isSupportedVersion(version), + 'QR code version $version is not supported', + ), + _data = data, + _qrCode = null; + + /// Create a new QR code using the [QrCode] data and the passed options (or + /// using the default options). + QrImageView.withQr({ + required QrCode qr, + super.key, + this.size, + this.padding = const EdgeInsets.all(10.0), + this.backgroundColor = Colors.transparent, + @Deprecated('use colors in eyeStyle and dataModuleStyle instead') + this.foregroundColor = Colors.black, + this.version = QrVersions.auto, + this.errorCorrectionLevel = QrErrorCorrectLevel.L, + this.errorStateBuilder, + this.constrainErrorBounds = true, + this.gapless = true, + this.embeddedImage, + this.embeddedImageStyle = const QrEmbeddedImageStyle(), + this.semanticsLabel = 'qr code', + this.eyeStyle = const QrEyeStyle( + eyeShape: QrEyeShape.square, + color: Colors.black, + ), + this.dataModuleStyle = const QrDataModuleStyle( + dataModuleShape: QrDataModuleShape.square, + color: Colors.black, + ), + this.embeddedImageEmitsError = false, + this.gradient, + }) : assert( + QrVersions.isSupportedVersion(version), + 'QR code version $version is not supported', + ), + _data = null, + _qrCode = qr; + + // The data passed to the widget + final String? _data; + + // The QR code data passed to the widget + final QrCode? _qrCode; + + /// The background color of the final QR code widget. + final Color backgroundColor; + + /// The foreground color of the final QR code widget. + @Deprecated('use colors in eyeStyle and dataModuleStyle instead') + final Color foregroundColor; + + /// The gradient for all (dataModule and eye) + final Gradient? gradient; + + /// The QR code version to use. + final int version; + + /// The QR code error correction level to use. + final int errorCorrectionLevel; + + /// The external padding between the edge of the widget and the content. + final EdgeInsets padding; + + /// The intended size of the widget. + final double? size; + + /// The callback that is executed in the event of an error so that you can + /// interrogate the exception and construct an alternative view to present + /// to your user. + final QrErrorBuilder? errorStateBuilder; + + /// If `true` then the error widget will be constrained to the boundary of the + /// QR widget if it had been valid. If `false` the error widget will grow to + /// the size it needs. If the error widget is allowed to grow, your layout may + /// jump around (depending on specifics). + /// + /// NOTE: Setting a [size] value will override this setting and both the + /// content widget and error widget will adhere to the size value. + final bool constrainErrorBounds; + + /// If set to false, each of the squares in the QR code will have a small + /// gap. Default is true. + final bool gapless; + + /// The image data to embed (as an overlay) in the QR code. The image will + /// be added to the center of the QR code. + final ImageProvider? embeddedImage; + + /// Styling options for the image overlay. + final QrEmbeddedImageStyle embeddedImageStyle; + + /// If set to true and there is an error loading the embedded image, the + /// [errorStateBuilder] callback will be called (if it is defined). If false, + /// the widget will ignore the embedded image and just display the QR code. + /// The default is false. + final bool embeddedImageEmitsError; + + /// [semanticsLabel] will be used by screen readers to describe the content of + /// the qr code. + /// Default is 'qr code'. + final String semanticsLabel; + + /// Styling option for QR Eye ball and frame. + final QrEyeStyle eyeStyle; + + /// Styling option for QR data module. + final QrDataModuleStyle dataModuleStyle; + + @override + State createState() => _QrImageViewState(); +} + +class _QrImageViewState extends State { + /// The QR code string data. + QrCode? _qr; + + /// The current validation status. + late QrValidationResult _validationResult; + + @override + Widget build(BuildContext context) { + if (widget._data != null) { + _validationResult = QrValidator.validate( + data: widget._data!, + version: widget.version, + errorCorrectionLevel: widget.errorCorrectionLevel, + ); + _qr = _validationResult.isValid ? _validationResult.qrCode : null; + } else if (widget._qrCode != null) { + _qr = widget._qrCode; + _validationResult = + QrValidationResult(status: QrValidationStatus.valid, qrCode: _qr); + } + return LayoutBuilder( + builder: (context, constraints) { + // validation failed, show an error state widget if builder is present. + if (!_validationResult.isValid) { + return _errorWidget(context, constraints, _validationResult.error); + } + // no error, build the regular widget + final widgetSize = + widget.size ?? constraints.biggest.shortestSide; + if (widget.embeddedImage != null) { + // if requesting to embed an image then we need to load via a + // FutureBuilder because the image provider will be async. + return FutureBuilder( + future: _loadQrImage(context, widget.embeddedImageStyle), + builder: (ctx, snapshot) { + if (snapshot.error != null) { + debugPrint('snapshot error: ${snapshot.error}'); + return widget.embeddedImageEmitsError + ? _errorWidget(context, constraints, snapshot.error) + : _qrWidget(null, widgetSize); + } + if (snapshot.hasData) { + debugPrint('loaded image'); + final loadedImage = snapshot.data; + return _qrWidget(loadedImage, widgetSize); + } else { + return Container(); + } + }, + ); + } else { + return _qrWidget(null, widgetSize); + } + }, + ); + } + + Widget _qrWidget(ui.Image? image, double edgeLength) { + final painter = QrPainter.withQr( + qr: _qr!, + // ignore: deprecated_member_use_from_same_package + color: widget.foregroundColor, + gapless: widget.gapless, + embeddedImageStyle: widget.embeddedImageStyle, + embeddedImage: image, + eyeStyle: widget.eyeStyle, + dataModuleStyle: widget.dataModuleStyle, + gradient: widget.gradient + ); + return _QrContentView( + edgeLength: edgeLength, + backgroundColor: widget.backgroundColor, + padding: widget.padding, + semanticsLabel: widget.semanticsLabel, + child: CustomPaint(painter: painter), + ); + } + + Widget _errorWidget( + BuildContext context, + BoxConstraints constraints, + Object? error, + ) { + final errorWidget = widget.errorStateBuilder == null + ? Container() + : widget.errorStateBuilder!(context, error); + final errorSideLength = widget.constrainErrorBounds + ? widget.size ?? constraints.biggest.shortestSide + : constraints.biggest.longestSide; + return _QrContentView( + edgeLength: errorSideLength, + backgroundColor: widget.backgroundColor, + padding: widget.padding, + semanticsLabel: widget.semanticsLabel, + child: errorWidget, + ); + } + + late ImageStreamListener streamListener; + + Future _loadQrImage( + BuildContext buildContext, + QrEmbeddedImageStyle? style, + ) { + if (style != null) {} + + final mq = MediaQuery.of(buildContext); + final completer = Completer(); + final stream = widget.embeddedImage!.resolve( + ImageConfiguration( + devicePixelRatio: mq.devicePixelRatio, + ), + ); + + streamListener = ImageStreamListener( + (info, err) { + stream.removeListener(streamListener); + completer.complete(info.image); + }, + onError: (err, _) { + stream.removeListener(streamListener); + completer.completeError(err); + }, + ); + stream.addListener(streamListener); + return completer.future; + } +} + +/// A function type to be called when any form of error occurs while +/// painting a [QrImageView]. +typedef QrErrorBuilder = Widget Function(BuildContext context, Object? error); + +class _QrContentView extends StatelessWidget { + const _QrContentView({ + required this.edgeLength, + required this.child, + this.backgroundColor, + this.padding, + this.semanticsLabel, + }); + + /// The length of both edges (because it has to be a square). + final double edgeLength; + + /// The background color of the containing widget. + final Color? backgroundColor; + + /// The padding that surrounds the child widget. + final EdgeInsets? padding; + + /// The child widget. + final Widget child; + + /// [semanticsLabel] will be used by screen readers to describe the content of + /// the qr code. + final String? semanticsLabel; + + @override + Widget build(BuildContext context) { + return Semantics( + label: semanticsLabel, + child: Container( + width: edgeLength, + height: edgeLength, + color: backgroundColor, + child: Padding( + padding: padding!, + child: child, + ), + ), + ); + } +} diff --git a/qr_flutter/lib/src/qr_painter.dart b/qr_flutter/lib/src/qr_painter.dart new file mode 100644 index 0000000..e773c57 --- /dev/null +++ b/qr_flutter/lib/src/qr_painter.dart @@ -0,0 +1,694 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +import 'dart:async'; +import 'dart:ui' as ui; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:qr/qr.dart'; + +import 'errors.dart'; +import 'paint_cache.dart'; +import 'qr_versions.dart'; +import 'types.dart'; +import 'validator.dart'; + +// ignore_for_file: deprecated_member_use_from_same_package + +const int _finderPatternLimit = 7; + +// default colors for the qr code pixels +const Color _qrDefaultColor = Color(0xff000000); +const Color _qrDefaultEmptyColor = Color(0x00ffffff); + +/// A [CustomPainter] object that you can use to paint a QR code. +class QrPainter extends CustomPainter { + /// Create a new QRPainter with passed options (or defaults). + QrPainter({ + required String data, + required this.version, + this.errorCorrectionLevel = QrErrorCorrectLevel.L, + @Deprecated('use colors in eyeStyle and dataModuleStyle instead') + this.color = _qrDefaultColor, + @Deprecated( + 'You should use the background color value of your container widget', + ) + this.emptyColor = _qrDefaultEmptyColor, + this.gapless = false, + this.embeddedImage, + this.embeddedImageStyle = const QrEmbeddedImageStyle(), + this.eyeStyle = const QrEyeStyle(), + this.dataModuleStyle = const QrDataModuleStyle(), + this.gradient, + }) : assert( + QrVersions.isSupportedVersion(version), + 'QR code version $version is not supported', + ) { + _init(data); + } + + /// Create a new QrPainter with a pre-validated/created [QrCode] object. This + /// constructor is useful when you have a custom validation / error handling + /// flow or for when you need to pre-validate the QR data. + QrPainter.withQr({ + required QrCode qr, + @Deprecated('use colors in eyeStyle and dataModuleStyle instead') + this.color = _qrDefaultColor, + @Deprecated( + 'You should use the background color value of your container widget', + ) + this.emptyColor = _qrDefaultEmptyColor, + this.gapless = false, + this.embeddedImage, + this.embeddedImageStyle = const QrEmbeddedImageStyle(), + this.eyeStyle = const QrEyeStyle(), + this.dataModuleStyle = const QrDataModuleStyle(), + this.gradient, + }) : _qr = qr, + version = qr.typeNumber, + errorCorrectionLevel = qr.errorCorrectLevel { + _calcVersion = version; + _initPaints(); + } + + /// The QR code version. + final int version; // the qr code version + + /// The error correction level of the QR code. + final int errorCorrectionLevel; // the qr code error correction level + + /// The color of the squares. + @Deprecated('use colors in eyeStyle and dataModuleStyle instead') + final Color color; + + /// The gradient for all (dataModuleShape, eyeShape, embeddedImageShape) + final Gradient? gradient; + + /// The color of the non-squares (background). + @Deprecated( + 'You should use the background color value of your container widget') + final Color emptyColor; // the other color + /// If set to false, the painter will leave a 1px gap between each of the + /// squares. + final bool gapless; + + /// The image data to embed (as an overlay) in the QR code. The image will + /// be added to the center of the QR code. + final ui.Image? embeddedImage; + + /// Styling options for the image overlay. + final QrEmbeddedImageStyle embeddedImageStyle; + + /// Styling option for QR Eye ball and frame. + final QrEyeStyle eyeStyle; + + /// Styling option for QR data module. + final QrDataModuleStyle dataModuleStyle; + + /// The base QR code data + QrCode? _qr; + + /// QR Image renderer + late QrImage _qrImage; + + /// This is the version (after calculating) that we will use if the user has + /// requested the 'auto' version. + late final int _calcVersion; + + /// The size of the 'gap' between the pixels + final double _gapSize = 0.25; + + /// Cache for all of the [Paint] objects. + final PaintCache _paintCache = PaintCache(); + + void _init(String data) { + if (!QrVersions.isSupportedVersion(version)) { + throw QrUnsupportedVersionException(version); + } + // configure and make the QR code data + final validationResult = QrValidator.validate( + data: data, + version: version, + errorCorrectionLevel: errorCorrectionLevel, + ); + if (!validationResult.isValid) { + throw validationResult.error!; + } + _qr = validationResult.qrCode; + _calcVersion = _qr!.typeNumber; + _initPaints(); + } + + void _initPaints() { + // Initialize `QrImage` for rendering + _qrImage = QrImage(_qr!); + // Cache the pixel paint object. For now there is only one but we might + // expand it to multiple later (e.g.: different colours). + _paintCache.cache( + Paint()..style = PaintingStyle.fill, + QrCodeElement.codePixel, + ); + // Cache the empty pixel paint object. Empty color is deprecated and will go + // away. + _paintCache.cache( + Paint()..style = PaintingStyle.fill, + QrCodeElement.codePixelEmpty, + ); + // Cache the finder pattern painters. We'll keep one for each one in case + // we want to provide customization options later. + for (final position in FinderPatternPosition.values) { + _paintCache.cache( + Paint()..style = PaintingStyle.stroke, + QrCodeElement.finderPatternOuter, + position: position, + ); + _paintCache.cache( + Paint()..style = PaintingStyle.stroke, + QrCodeElement.finderPatternInner, + position: position, + ); + _paintCache.cache( + Paint()..style = PaintingStyle.fill, + QrCodeElement.finderPatternDot, + position: position, + ); + } + } + + @override + void paint(Canvas canvas, Size size) { + // if the widget has a zero size side then we cannot continue painting. + if (size.shortestSide == 0) { + debugPrint( + "[QR] WARN: width or height is zero. You should set a 'size' value " + 'or nest this painter in a Widget that defines a non-zero size'); + return; + } + + final paintMetrics = _PaintMetrics( + containerSize: size.shortestSide, + moduleCount: _qr!.moduleCount, + gapSize: gapless ? 0 : _gapSize, + ); + + // draw the finder pattern elements + _drawFinderPatternItem( + FinderPatternPosition.topLeft, + canvas, + paintMetrics, + ); + _drawFinderPatternItem( + FinderPatternPosition.bottomLeft, + canvas, + paintMetrics, + ); + _drawFinderPatternItem( + FinderPatternPosition.topRight, + canvas, + paintMetrics, + ); + + // DEBUG: draw the inner content boundary +// final paint = Paint()..style = ui.PaintingStyle.stroke; +// paint.strokeWidth = 1; +// paint.color = const Color(0x55222222); +// canvas.drawRect( +// Rect.fromLTWH(paintMetrics.inset, paintMetrics.inset, +// paintMetrics.innerContentSize, paintMetrics.innerContentSize), +// paint); + + Size? embeddedImageSize; + Offset? embeddedImagePosition; + Offset? safeAreaPosition; + Rect? safeAreaRect; + if (embeddedImage != null) { + final originalSize = Size( + embeddedImage!.width.toDouble(), + embeddedImage!.height.toDouble(), + ); + final requestedSize = embeddedImageStyle.size; + embeddedImageSize = _scaledAspectSize(size, originalSize, requestedSize); + embeddedImagePosition = Offset( + (size.width - embeddedImageSize.width) / 2.0, + (size.height - embeddedImageSize.height) / 2.0, + ); + if(embeddedImageStyle.safeArea) { + final safeAreaMultiplier = embeddedImageStyle.safeAreaMultiplier; + safeAreaPosition = Offset( + (size.width - embeddedImageSize.width * safeAreaMultiplier) / 2.0, + (size.height - embeddedImageSize.height * safeAreaMultiplier) / 2.0, + ); + safeAreaRect = Rect.fromLTWH( + safeAreaPosition.dx, + safeAreaPosition.dy, + embeddedImageSize.width * safeAreaMultiplier, + embeddedImageSize.height * safeAreaMultiplier, + ); + } + + if(embeddedImageStyle.embeddedImageShape != EmbeddedImageShape.none) { + final color = _priorityColor(embeddedImageStyle.shapeColor); + + final squareRect = Rect.fromLTWH( + embeddedImagePosition.dx, + embeddedImagePosition.dy, + embeddedImageSize.width, + embeddedImageSize.height, + ); + + final paint = Paint()..color = color; + + switch(embeddedImageStyle.embeddedImageShape) { + case EmbeddedImageShape.square: + if(embeddedImageStyle.borderRadius > 0) { + final roundedRect = RRect.fromRectAndRadius( + squareRect, + Radius.circular(embeddedImageStyle.borderRadius), + ); + canvas.drawRRect(roundedRect, paint); + } else { + canvas.drawRect(squareRect, paint); + } + break; + case EmbeddedImageShape.circle: + final roundedRect = RRect.fromRectAndRadius(squareRect, + Radius.circular(squareRect.width / 2)); + canvas.drawRRect(roundedRect, paint); + break; + default: + break; + } + } + } + + final gap = !gapless ? _gapSize : 0; + // get the painters for the pixel information + final pixelPaint = _paintCache.firstPaint(QrCodeElement.codePixel); + pixelPaint!.color = _priorityColor(dataModuleStyle.color); + + final emptyPixelPaint = _paintCache + .firstPaint(QrCodeElement.codePixelEmpty); + emptyPixelPaint!.color = _qrDefaultEmptyColor; + + final borderRadius = Radius + .circular(dataModuleStyle.borderRadius); + final outsideBorderRadius = Radius + .circular(dataModuleStyle.outsideBorderRadius); + final isRoundedOutsideCorners = dataModuleStyle.roundedOutsideCorners; + + for (var x = 0; x < _qr!.moduleCount; x++) { + for (var y = 0; y < _qr!.moduleCount; y++) { + // draw the finder patterns independently + if (_isFinderPatternPosition(x, y)) { + continue; + } + final isDark = _qrImage.isDark(y, x); + final paint = isDark ? pixelPaint : emptyPixelPaint; + if (!isDark && !isRoundedOutsideCorners) { + continue; + } + // paint a pixel + final squareRect = _createDataModuleRect(paintMetrics, x, y, gap); + // check safeArea + if(embeddedImageStyle.safeArea + && safeAreaRect?.overlaps(squareRect) == true) continue; + switch(dataModuleStyle.dataModuleShape) { + case QrDataModuleShape.square: + if(dataModuleStyle.borderRadius > 0) { + + // If pixel isDark == true and outside safe area + // than can't be rounded + final isDarkLeft = _isDarkOnSide(x - 1, y, + safeAreaRect, paintMetrics, gap); + final isDarkTop = _isDarkOnSide(x, y - 1, + safeAreaRect, paintMetrics, gap); + final isDarkRight = _isDarkOnSide(x + 1, y, + safeAreaRect, paintMetrics, gap); + final isDarkBottom = _isDarkOnSide(x, y + 1, + safeAreaRect, paintMetrics, gap); + + if(!isDark && isRoundedOutsideCorners) { + final isDarkTopLeft = _isDarkOnSide(x - 1, y - 1, + safeAreaRect, paintMetrics, gap);; + final isDarkTopRight = _isDarkOnSide(x + 1, y - 1, + safeAreaRect, paintMetrics, gap);; + final isDarkBottomLeft = _isDarkOnSide(x - 1, y + 1, + safeAreaRect, paintMetrics, gap);; + final isDarkBottomRight = _isDarkOnSide(x + 1, y + 1, + safeAreaRect, paintMetrics, gap);; + + final roundedRect = RRect.fromRectAndCorners( + squareRect, + topLeft: isDarkTop && isDarkLeft && isDarkTopLeft + ? outsideBorderRadius + : Radius.zero, + topRight: isDarkTop && isDarkRight && isDarkTopRight + ? outsideBorderRadius + : Radius.zero, + bottomLeft: isDarkBottom && isDarkLeft && isDarkBottomLeft + ? outsideBorderRadius + : Radius.zero, + bottomRight: isDarkBottom && isDarkRight && isDarkBottomRight + ? outsideBorderRadius + : Radius.zero, + ); + canvas.drawPath( + Path.combine( + PathOperation.difference, + Path()..addRect(squareRect), + Path()..addRRect(roundedRect)..close(), + ), + pixelPaint, + ); + } else { + final roundedRect = RRect.fromRectAndCorners( + squareRect, + topLeft: isDarkTop || isDarkLeft + ? Radius.zero + : borderRadius, + topRight: isDarkTop || isDarkRight + ? Radius.zero + : borderRadius, + bottomLeft: isDarkBottom || isDarkLeft + ? Radius.zero + : borderRadius, + bottomRight: isDarkBottom || isDarkRight + ? Radius.zero + : borderRadius, + ); + canvas.drawRRect(roundedRect, paint); + } + } else { + canvas.drawRect(squareRect, paint); + } + break; + default: + final roundedRect = RRect.fromRectAndRadius(squareRect, + Radius.circular(squareRect.width / 2)); + canvas.drawRRect(roundedRect, paint); + break; + } + } + } + + // set gradient for all + if(gradient != null) { + final paintGradient = Paint(); + paintGradient.shader = gradient! + .createShader(Rect.fromLTWH(0, 0, size.width, size.height)); + paintGradient.blendMode = BlendMode.values[12]; + canvas.drawRect( + Rect.fromLTWH( + paintMetrics.inset, + paintMetrics.inset, + paintMetrics.innerContentSize, + paintMetrics.innerContentSize, + ), + paintGradient, + ); + } + + // draw the image overlay. + if (embeddedImage != null) { + _drawImageOverlay( + canvas, + embeddedImagePosition!, + embeddedImageSize!, + embeddedImageStyle, + ); + } + } + + bool _isDarkOnSide(int x, int y, Rect? safeAreaRect, + _PaintMetrics paintMetrics, num gap,) { + final maxIndexPixel = _qrImage.moduleCount - 1; + + final xIsContains = x >= 0 && x <= maxIndexPixel; + final yIsContains = y >= 0 && y <= maxIndexPixel; + + return xIsContains && yIsContains + ? _qrImage.isDark(y, x) + && !(safeAreaRect?.overlaps( + _createDataModuleRect(paintMetrics, x, y, gap)) + ?? false) + : false; + } + + Rect _createDataModuleRect(_PaintMetrics paintMetrics, int x, int y, num gap) { + final left = paintMetrics.inset + (x * (paintMetrics.pixelSize + gap)); + final top = paintMetrics.inset + (y * (paintMetrics.pixelSize + gap)); + var pixelHTweak = 0.0; + var pixelVTweak = 0.0; + if (gapless && _hasAdjacentHorizontalPixel(x, y, _qr!.moduleCount)) { + pixelHTweak = 0.5; + } + if (gapless && _hasAdjacentVerticalPixel(x, y, _qr!.moduleCount)) { + pixelVTweak = 0.5; + } + return Rect.fromLTWH( + left, + top, + paintMetrics.pixelSize + pixelHTweak, + paintMetrics.pixelSize + pixelVTweak, + ); + } + + bool _hasAdjacentVerticalPixel(int x, int y, int moduleCount) { + if (y + 1 >= moduleCount) { + return false; + } + return _qrImage.isDark(y + 1, x); + } + + bool _hasAdjacentHorizontalPixel(int x, int y, int moduleCount) { + if (x + 1 >= moduleCount) { + return false; + } + return _qrImage.isDark(y, x + 1); + } + + bool _isFinderPatternPosition(int x, int y) { + final isTopLeft = y < _finderPatternLimit && x < _finderPatternLimit; + final isBottomLeft = y < _finderPatternLimit && + (x >= _qr!.moduleCount - _finderPatternLimit); + final isTopRight = y >= _qr!.moduleCount - _finderPatternLimit && + (x < _finderPatternLimit); + return isTopLeft || isBottomLeft || isTopRight; + } + + void _drawFinderPatternItem( + FinderPatternPosition position, + Canvas canvas, + _PaintMetrics metrics, + ) { + final totalGap = (_finderPatternLimit - 1) * metrics.gapSize; + final radius = + ((_finderPatternLimit * metrics.pixelSize) + totalGap) - + metrics.pixelSize; + final strokeAdjust = metrics.pixelSize / 2.0; + final edgePos = + (metrics.inset + metrics.innerContentSize) - (radius + strokeAdjust); + + Offset offset; + if (position == FinderPatternPosition.topLeft) { + offset = + Offset(metrics.inset + strokeAdjust, metrics.inset + strokeAdjust); + } else if (position == FinderPatternPosition.bottomLeft) { + offset = Offset(metrics.inset + strokeAdjust, edgePos); + } else { + offset = Offset(edgePos, metrics.inset + strokeAdjust); + } + + // configure the paints + final outerPaint = _paintCache.firstPaint( + QrCodeElement.finderPatternOuter, + position: position, + )!; + final color = _priorityColor(eyeStyle.color); + outerPaint.strokeWidth = metrics.pixelSize; + outerPaint.color = color; + + final innerPaint = _paintCache + .firstPaint(QrCodeElement.finderPatternInner, position: position)!; + innerPaint.strokeWidth = metrics.pixelSize; + innerPaint.color = emptyColor; + + final dotPaint = _paintCache.firstPaint( + QrCodeElement.finderPatternDot, + position: position, + ); + dotPaint!.color = color; + + final outerRect = + Rect.fromLTWH(offset.dx, offset.dy, radius, radius); + + final innerRadius = radius - (2 * metrics.pixelSize); + final innerRect = Rect.fromLTWH( + offset.dx + metrics.pixelSize, + offset.dy + metrics.pixelSize, + innerRadius, + innerRadius, + ); + + final gap = metrics.pixelSize * 2; + final dotSize = radius - gap - (2 * strokeAdjust); + final dotRect = Rect.fromLTWH( + offset.dx + metrics.pixelSize + strokeAdjust, + offset.dy + metrics.pixelSize + strokeAdjust, + dotSize, + dotSize, + ); + + 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; + } + } + + bool _hasOneNonZeroSide(Size size) => size.longestSide > 0; + + Size _scaledAspectSize( + Size widgetSize, + Size originalSize, + Size? requestedSize, + ) { + if (requestedSize != null && !requestedSize.isEmpty) { + return requestedSize; + } else if (requestedSize != null && _hasOneNonZeroSide(requestedSize)) { + final maxSide = requestedSize.longestSide; + final ratio = maxSide / originalSize.longestSide; + return Size(ratio * originalSize.width, ratio * originalSize.height); + } else { + final maxSide = 0.25 * widgetSize.shortestSide; + final ratio = maxSide / originalSize.longestSide; + return Size(ratio * originalSize.width, ratio * originalSize.height); + } + } + + void _drawImageOverlay( + Canvas canvas, + Offset position, + Size size, + QrEmbeddedImageStyle? style, + ) { + final paint = Paint() + ..isAntiAlias = true + ..filterQuality = FilterQuality.high; + if (style != null) { + if (style.color != null) { + paint.colorFilter = ColorFilter.mode(style.color!, BlendMode.srcATop); + } + } + final srcSize = Size( + embeddedImage!.width.toDouble(), + embeddedImage!.height.toDouble(), + ); + final src = Alignment.center.inscribe(srcSize, Offset.zero & srcSize); + final dst = Alignment.center.inscribe(size, position & size); + canvas.drawImageRect(embeddedImage!, src, dst, paint); + } + + /// if [gradient] != null, then only black [_qrDefaultColor], + /// needed for gradient + /// else [color] or [QrPainter.color] + Color _priorityColor(Color? color) => + gradient != null ? _qrDefaultColor : color ?? this.color; + + @override + bool shouldRepaint(CustomPainter oldPainter) { + if (oldPainter is QrPainter) { + return errorCorrectionLevel != oldPainter.errorCorrectionLevel || + _calcVersion != oldPainter._calcVersion || + _qr != oldPainter._qr || + gapless != oldPainter.gapless || + embeddedImage != oldPainter.embeddedImage || + embeddedImageStyle != oldPainter.embeddedImageStyle || + eyeStyle != oldPainter.eyeStyle || + dataModuleStyle != oldPainter.dataModuleStyle; + } + return true; + } + + /// Returns a [ui.Picture] object containing the QR code data. + ui.Picture toPicture(double size) { + final recorder = ui.PictureRecorder(); + final canvas = Canvas(recorder); + paint(canvas, Size(size, size)); + return recorder.endRecording(); + } + + /// Returns the raw QR code [ui.Image] object. + Future toImage(double size) { + return toPicture(size).toImage(size.toInt(), size.toInt()); + } + + /// Returns the raw QR code image byte data. + Future toImageData( + double size, { + ui.ImageByteFormat format = ui.ImageByteFormat.png, + }) async { + final image = await toImage(size); + return image.toByteData(format: format); + } +} + +class _PaintMetrics { + _PaintMetrics({ + required this.containerSize, + required this.gapSize, + required this.moduleCount, + }) { + _calculateMetrics(); + } + + final int moduleCount; + final double containerSize; + final double gapSize; + + late final double _pixelSize; + double get pixelSize => _pixelSize; + + late final double _innerContentSize; + double get innerContentSize => _innerContentSize; + + late final double _inset; + double get inset => _inset; + + void _calculateMetrics() { + final gapTotal = (moduleCount - 1) * gapSize; + final pixelSize = (containerSize - gapTotal) / moduleCount; + _pixelSize = (pixelSize * 2).roundToDouble() / 2; + _innerContentSize = (_pixelSize * moduleCount) + gapTotal; + _inset = (containerSize - _innerContentSize) / 2; + } +} diff --git a/qr_flutter/lib/src/qr_versions.dart b/qr_flutter/lib/src/qr_versions.dart new file mode 100644 index 0000000..0d4713f --- /dev/null +++ b/qr_flutter/lib/src/qr_versions.dart @@ -0,0 +1,23 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +/// This class only contains special version codes. QR codes support version +/// numbers from 1-40 and you should just use the numeric version directly. +class QrVersions { + /// Automatically determine the QR code version based on input and an + /// error correction level. + static const int auto = -1; + + /// The minimum supported version code. + static const int min = 1; + + /// The maximum supported version code. + static const int max = 40; + + /// Checks to see if the supplied version is a valid QR code version + static bool isSupportedVersion(int version) => + version == auto || (version >= min && version <= max); +} diff --git a/qr_flutter/lib/src/types.dart b/qr_flutter/lib/src/types.dart new file mode 100644 index 0000000..07a85e9 --- /dev/null +++ b/qr_flutter/lib/src/types.dart @@ -0,0 +1,208 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +import 'package:flutter/widgets.dart'; +import 'dart:ui'; + + +/// Represents a specific element / part of a QR code. This is used to isolate +/// the different parts so that we can style and modify specific parts +/// independently. +enum QrCodeElement { + /// The 'stroke' / outer square of the QR code finder pattern element. + finderPatternOuter, + + /// The inner/in-between square of the QR code finder pattern element. + finderPatternInner, + + /// The "dot" square of the QR code finder pattern element. + finderPatternDot, + + /// The individual pixels of the QR code + codePixel, + + /// The "empty" pixels of the QR code + codePixelEmpty, +} + +/// Enumeration representing the three finder pattern (square 'eye') locations. +enum FinderPatternPosition { + /// The top left position. + topLeft, + + /// The top right position. + topRight, + + /// The bottom left position. + bottomLeft, +} + +/// Enumeration representing the finder pattern eye's shape. +enum QrEyeShape { + /// Use square eye frame. + square, + + /// Use circular eye frame. + circle, +} + +/// Enumeration representing the shape of Data modules inside QR. +enum QrDataModuleShape { + /// Use square dots. + square, + + /// Use circular dots. + circle, +} + +/// Enumeration representing the shape behind embedded picture +enum EmbeddedImageShape { + /// Disable + none, + + /// Use square. + square, + + /// Use circular. + circle, +} + +/// Styling options for finder pattern eye. +@immutable +class QrEyeStyle { + /// Create a new set of styling options for QR Eye. + const QrEyeStyle({ + this.eyeShape = QrEyeShape.square, + 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; + + @override + bool operator ==(Object other) { + if (other is QrEyeStyle) { + return eyeShape == other.eyeShape && color == other.color; + } + return false; + } +} + +/// Styling options for data module. +@immutable +class QrDataModuleStyle { + /// Create a new set of styling options for data modules. + const QrDataModuleStyle({ + this.dataModuleShape = QrDataModuleShape.square, + this.color, + this.borderRadius = 0, + this.roundedOutsideCorners = false, + double? outsideBorderRadius, + }) : _outsideBorderRadius = outsideBorderRadius; + + /// Data module shape. + final QrDataModuleShape dataModuleShape; + + /// Color to tint the data modules. + final Color? color; + + /// Border radius + final double borderRadius; + + /// Only [QrDataModuleShape.square] + /// true for rounded outside corners + final bool roundedOutsideCorners; + + /// Only [QrDataModuleShape.square] + /// Border radius for outside corners + final double? _outsideBorderRadius; + + /// if [roundedOutsideCorners] == true, then by default use [borderRadius] + /// [_outsideBorderRadius] <= [borderRadius] + /// Get border radius for outside corners + double get outsideBorderRadius { + if(roundedOutsideCorners) { + return _outsideBorderRadius != null + && _outsideBorderRadius! < borderRadius + ? _outsideBorderRadius! : borderRadius; + } + return 0; + } + + @override + int get hashCode => dataModuleShape.hashCode ^ color.hashCode; + + @override + bool operator ==(Object other) { + if (other is QrDataModuleStyle) { + return dataModuleShape == other.dataModuleShape && color == other.color; + } + return false; + } +} + +/// Styling options for any embedded image overlay +@immutable +class QrEmbeddedImageStyle { + /// Create a new set of styling options. + const QrEmbeddedImageStyle({ + this.size, + this.color, + this.safeArea = false, + this.safeAreaMultiplier = 1, + this.embeddedImageShape = EmbeddedImageShape.none, + this.shapeColor, + this.borderRadius = 0, + }); + + /// The size of the image. If one dimension is zero then the other dimension + /// will be used to scale the zero dimension based on the original image + /// size. + final Size? size; + + /// Color to tint the image. + final Color? color; + + /// Hide data modules behind embedded image. + /// Data modules are not displayed inside area + final bool safeArea; + + /// Safe area size multiplier. + final double safeAreaMultiplier; + + /// Shape background embedded image + final EmbeddedImageShape embeddedImageShape; + + /// Border radius shape + final double borderRadius; + + /// Color background + final Color? shapeColor; + + /// Check to see if the style object has a non-null, non-zero size. + bool get hasDefinedSize => size != null && size!.longestSide > 0; + + @override + int get hashCode => size.hashCode ^ color.hashCode; + + @override + bool operator ==(Object other) { + if (other is QrEmbeddedImageStyle) { + return size == other.size && color == other.color; + } + return false; + } +} diff --git a/qr_flutter/lib/src/validator.dart b/qr_flutter/lib/src/validator.dart new file mode 100644 index 0000000..12a1eb8 --- /dev/null +++ b/qr_flutter/lib/src/validator.dart @@ -0,0 +1,80 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +import 'package:qr/qr.dart'; + +import 'qr_versions.dart'; + +/// A utility class for validating and pre-rendering QR code data. +class QrValidator { + /// Attempt to parse / generate the QR code data and check for any errors. The + /// resulting [QrValidationResult] object will hold the status of the QR code + /// as well as the generated QR code data. + static QrValidationResult validate({ + required String data, + int version = QrVersions.auto, + int errorCorrectionLevel = QrErrorCorrectLevel.L, + }) { + late final QrCode qrCode; + try { + if (version != QrVersions.auto) { + qrCode = QrCode(version, errorCorrectionLevel); + qrCode.addData(data); + } else { + qrCode = QrCode.fromData( + data: data, + errorCorrectLevel: errorCorrectionLevel, + ); + } + return QrValidationResult( + status: QrValidationStatus.valid, + qrCode: qrCode, + ); + } on InputTooLongException catch (title) { + return QrValidationResult( + status: QrValidationStatus.contentTooLong, + error: title, + ); + } on Exception catch (ex) { + return QrValidationResult(status: QrValidationStatus.error, error: ex); + } + } +} + +/// Captures the status or a QR code validation operations, as well as the +/// rendered and validated data / object so that it can be used in any +/// secondary operations (to avoid re-rendering). It also keeps any exception +/// that was thrown. +class QrValidationResult { + /// Create a new validation result instance. + QrValidationResult({required this.status, this.qrCode, this.error}); + + /// The status of the validation operation. + QrValidationStatus status; + + /// The rendered QR code data / object. + QrCode? qrCode; + + /// The exception that was thrown in the event of a non-valid result (if any). + Exception? error; + + /// The validation result returned a status of valid; + bool get isValid => status == QrValidationStatus.valid; +} + +/// The status of the QR code data you requested to be validated. +enum QrValidationStatus { + /// The QR code data is valid for the provided parameters. + valid, + + /// The QR code data is too long for the provided version + error check + /// configuration or too long to be contained in a QR code. + contentTooLong, + + /// An unknown / unexpected error occurred when we tried to validate the QR + /// code data. + error, +} diff --git a/qr_flutter/pubspec.lock b/qr_flutter/pubspec.lock new file mode 100644 index 0000000..002bb64 --- /dev/null +++ b/qr_flutter/pubspec.lock @@ -0,0 +1,197 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.dev" + source: hosted + version: "2.13.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + characters: + dependency: transitive + description: + name: characters + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + qr: + dependency: "direct main" + description: + name: qr + sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_span: + dependency: transitive + description: + name: source_span + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + url: "https://pub.dev" + source: hosted + version: "1.10.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test_api: + dependency: transitive + description: + name: test_api + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + url: "https://pub.dev" + source: hosted + version: "0.7.7" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + url: "https://pub.dev" + source: hosted + version: "15.0.2" +sdks: + dart: ">=3.8.0-0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/qr_flutter/pubspec.yaml b/qr_flutter/pubspec.yaml new file mode 100644 index 0000000..f0e2e74 --- /dev/null +++ b/qr_flutter/pubspec.yaml @@ -0,0 +1,22 @@ +name: qr_flutter +description: > + QR.Flutter is a Flutter library for simple and fast QR code rendering via a + Widget or custom painter. +version: 4.1.0 +homepage: https://github.com/theyakka/qr.flutter + +environment: + sdk: '>=2.19.6 <4.0.0' + flutter: ">=3.7.0" + +dependencies: + flutter: + sdk: flutter + qr: ^3.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + uses-material-design: false diff --git a/qr_flutter/test/.golden/qr_image_data_module_styled_golden.png b/qr_flutter/test/.golden/qr_image_data_module_styled_golden.png new file mode 100644 index 0000000000000000000000000000000000000000..d50b737da1c1eaa3014202dfd9161ea80e5e5e94 GIT binary patch literal 32358 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 VNTUo_#X(OHyZwi3?pgbt{RcrQ>vRAB literal 0 HcmV?d00001 diff --git a/qr_flutter/test/.golden/qr_image_eye_styled_golden.png b/qr_flutter/test/.golden/qr_image_eye_styled_golden.png new file mode 100644 index 0000000000000000000000000000000000000000..867ae26c4bca8d37435b3c9ec062395b30e9c666 GIT binary patch literal 15879 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 literal 0 HcmV?d00001 diff --git a/qr_flutter/test/.golden/qr_image_golden.png b/qr_flutter/test/.golden/qr_image_golden.png new file mode 100644 index 0000000000000000000000000000000000000000..493c247457e54cbcad53ad994d85d94c9f8dd944 GIT binary patch literal 5035 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 literal 0 HcmV?d00001 diff --git a/qr_flutter/test/.golden/qr_image_logo_golden.png b/qr_flutter/test/.golden/qr_image_logo_golden.png new file mode 100644 index 0000000000000000000000000000000000000000..8856a1b36837549bb6cf8f1207b3b5302f5e66de GIT binary patch literal 12850 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 literal 0 HcmV?d00001 diff --git a/qr_flutter/test/.golden/qr_painter_golden.png b/qr_flutter/test/.golden/qr_painter_golden.png new file mode 100644 index 0000000000000000000000000000000000000000..8b1ab8c7626f99c15724bfa1b8efad8ea2ab5712 GIT binary patch literal 1505 zcmeAS@N?(olHy`uVBq!ia0y~yV2S`?4mP03zO)&4fD~hKkh>GZx^prwfgF}%C(jTL zAgJL;>0n@B?e=tW45^s&_8=oKQ1;M*@BX=b<_mz#Q7{?;qaiRF0;3^7pAcvWXZ|yp UfzdlnhYw_-r>mdKI;Vst00ZS4u>b%7 literal 0 HcmV?d00001 diff --git a/qr_flutter/test/.images/logo_yakka.png b/qr_flutter/test/.images/logo_yakka.png new file mode 100644 index 0000000000000000000000000000000000000000..dabd102099af5aa2008e31b3d3e09471ad92a24d GIT binary patch literal 8424 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 L`tyosh>-sS9UvnQ literal 0 HcmV?d00001 diff --git a/qr_flutter/test/all_test.dart b/qr_flutter/test/all_test.dart new file mode 100644 index 0000000..58683ca --- /dev/null +++ b/qr_flutter/test/all_test.dart @@ -0,0 +1,14 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ +import 'package:flutter_test/flutter_test.dart'; + +import 'image_test.dart' as image; +import 'painter_test.dart' as painter; + +void main() { + group('image:', image.main); + group('painter:', painter.main); +} diff --git a/qr_flutter/test/image_test.dart b/qr_flutter/test/image_test.dart new file mode 100644 index 0000000..578c1c8 --- /dev/null +++ b/qr_flutter/test/image_test.dart @@ -0,0 +1,218 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:qr_flutter/qr_flutter.dart'; + +void main() { + testWidgets('QrImageView generates correct image', ( + tester, + ) async { + final qrImage = MaterialApp( + home: Center( + child: RepaintBoundary( + child: QrImageView( + data: 'This is a test image', + version: QrVersions.auto, + gapless: true, + errorCorrectionLevel: QrErrorCorrectLevel.L, + ), + ), + ), + ); + await tester.pumpWidget(qrImage); + await expectLater( + find.byType(QrImageView), + matchesGoldenFile('./.golden/qr_image_golden.png'), + ); + }); + + testWidgets( + 'QrImageView generates correct image with eye style', + (tester) async { + final qrImage = MaterialApp( + home: Center( + child: RepaintBoundary( + child: QrImageView( + data: 'This is a test image', + version: QrVersions.auto, + gapless: true, + errorCorrectionLevel: QrErrorCorrectLevel.L, + eyeStyle: const QrEyeStyle( + eyeShape: QrEyeShape.circle, + color: Colors.green, + ), + ), + ), + ), + ); + await tester.pumpWidget(qrImage); + await expectLater( + find.byType(QrImageView), + matchesGoldenFile('./.golden/qr_image_eye_styled_golden.png'), + ); + }, + ); + + testWidgets( + 'QrImageView generates correct image with data module style', + (tester) async { + final qrImage = MaterialApp( + home: Center( + child: RepaintBoundary( + child: QrImageView( + data: 'This is a test image', + version: QrVersions.auto, + gapless: true, + errorCorrectionLevel: QrErrorCorrectLevel.L, + dataModuleStyle: const QrDataModuleStyle( + dataModuleShape: QrDataModuleShape.circle, + color: Colors.blue, + ), + ), + ), + ), + ); + await tester.pumpWidget(qrImage); + await expectLater( + find.byType(QrImageView), + matchesGoldenFile('./.golden/qr_image_data_module_styled_golden.png'), + ); + }, + ); + + testWidgets( + 'QrImageView generates correct image with eye and data module sytle', + (tester) async { + final qrImage = MaterialApp( + home: Center( + child: RepaintBoundary( + child: QrImageView( + data: 'This is a test image', + version: QrVersions.auto, + gapless: true, + errorCorrectionLevel: QrErrorCorrectLevel.L, + eyeStyle: const QrEyeStyle( + eyeShape: QrEyeShape.circle, + color: Colors.green, + ), + dataModuleStyle: const QrDataModuleStyle( + dataModuleShape: QrDataModuleShape.circle, + color: Colors.blue, + ), + ), + ), + ), + ); + await tester.pumpWidget(qrImage); + await expectLater( + find.byType(QrImageView), + matchesGoldenFile( + './.golden/qr_image_eye_data_module_styled_golden.png', + ), + ); + }, + ); + + testWidgets( + 'QrImageView does not apply eye and data module color when foreground ' + 'color is also specified', + (tester) async { + final qrImage = MaterialApp( + home: Center( + child: RepaintBoundary( + child: QrImageView( + data: 'This is a test image', + version: QrVersions.auto, + gapless: true, + // ignore: deprecated_member_use_from_same_package + foregroundColor: Colors.red, + errorCorrectionLevel: QrErrorCorrectLevel.L, + eyeStyle: const QrEyeStyle( + eyeShape: QrEyeShape.circle, + color: Colors.green, + ), + dataModuleStyle: const QrDataModuleStyle( + dataModuleShape: QrDataModuleShape.circle, + color: Colors.blue, + ), + ), + ), + ), + ); + await tester.pumpWidget(qrImage); + await expectLater( + find.byType(QrImageView), + matchesGoldenFile('./.golden/qr_image_foreground_colored_golden.png'), + ); + }, + ); + + testWidgets( + 'QrImageView generates correct image with logo', + (tester) async { + await pumpWidgetWithImages( + tester, + MaterialApp( + home: Center( + child: RepaintBoundary( + child: QrImageView( + data: 'This is a a qr code with a logo', + version: QrVersions.auto, + gapless: true, + errorCorrectionLevel: QrErrorCorrectLevel.L, + embeddedImage: FileImage(File('test/.images/logo_yakka.png')), + ), + ), + ), + ), + ['test/.images/logo_yakka.png'], + ); + + await tester.pumpAndSettle(); + + await expectLater( + find.byType(QrImageView), + matchesGoldenFile('./.golden/qr_image_logo_golden.png'), + ); + }, + ); +} + +/// Pre-cache images to make sure they show up in golden tests. +/// +/// See https://github.com/flutter/flutter/issues/36552 for more info. +Future pumpWidgetWithImages( + WidgetTester tester, + Widget widget, + List assetNames, +) async { + Future? precacheFuture; + await tester.pumpWidget( + Builder( + builder: (buildContext) { + precacheFuture = tester.runAsync(() async { + await Future.wait(>[ + for (final String assetName in assetNames) + precacheImage(FileImage(File(assetName)), buildContext), + ]); + }); + return widget; + }, + ), + ); + await precacheFuture; +} + +Widget buildTestableWidget(Widget widget) { + return MediaQuery( + data: const MediaQueryData(), + child: MaterialApp(home: widget), + ); +} diff --git a/qr_flutter/test/painter_test.dart b/qr_flutter/test/painter_test.dart new file mode 100644 index 0000000..3e292c9 --- /dev/null +++ b/qr_flutter/test/painter_test.dart @@ -0,0 +1,41 @@ +/* + * QR.Flutter + * Copyright (c) 2019 the QR.Flutter authors. + * See LICENSE for distribution and usage details. + */ +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:qr_flutter/qr_flutter.dart'; + +void main() { + testWidgets('QrPainter generates correct image', (tester) async { + final painter = QrPainter( + data: 'The painter is this thing', + version: QrVersions.auto, + gapless: true, + errorCorrectionLevel: QrErrorCorrectLevel.L, + ); + ByteData? imageData; + await tester.runAsync(() async { + imageData = await painter.toImageData(600.0); + }); + final imageBytes = imageData!.buffer.asUint8List(); + final Widget widget = Center( + child: RepaintBoundary( + child: SizedBox( + width: 600, + height: 600, + child: Image.memory(imageBytes), + ), + ), + ); + await tester.pumpWidget(widget); + await tester.pumpAndSettle(); + await expectLater( + find.byType(RepaintBoundary), + matchesGoldenFile('./.golden/qr_painter_golden.png'), + ); + }); +}