David PHAM-VAN

Add Barcode and QRCode Widgets

# Changelog
## 1.3.28
- Add Barcode Widget
- Add QrCode Widget
## 1.3.27
- Add Roll Paper support
... ...
... ... @@ -22,9 +22,12 @@ import 'dart:typed_data';
import 'package:meta/meta.dart';
import 'package:pdf/pdf.dart';
import 'package:qr/qr.dart';
import 'package:barcode/barcode.dart';
import 'package:vector_math/vector_math_64.dart';
part 'widgets/annotations.dart';
part 'widgets/barcode.dart';
part 'widgets/basic.dart';
part 'widgets/clip.dart';
part 'widgets/container.dart';
... ... @@ -40,6 +43,7 @@ part 'widgets/page.dart';
part 'widgets/page_theme.dart';
part 'widgets/placeholders.dart';
part 'widgets/progress.dart';
part 'widgets/qrcode.dart';
part 'widgets/stack.dart';
part 'widgets/table.dart';
part 'widgets/text.dart';
... ...
/*
* Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ignore_for_file: omit_local_variable_types
part of widget;
class _BarcodeWidget extends Widget {
_BarcodeWidget({
@required this.data,
this.barcode,
this.color = PdfColors.black,
});
/// the barcode data
final String data;
final Barcode barcode;
final PdfColor color;
@override
void layout(Context context, BoxConstraints constraints,
{bool parentUsesSize = false}) {
box = PdfRect.fromPoints(PdfPoint.zero, constraints.biggest);
}
@override
void paint(Context context) {
super.paint(context);
final BarcodeDraw draw = barcode.draw;
if (draw is _BarcodeDraw) {
draw
..canvas = context.canvas
..left = box.left
..top = box.top;
}
context.canvas.setFillColor(color);
barcode.make(data, box.width, box.height);
context.canvas.fillPath();
}
}
class _BarcodeDraw extends BarcodeDraw {
PdfGraphics canvas;
double left;
double top;
@override
void fillRect(
double left, double top, double width, double height, bool black) {
if (black) {
canvas.drawRect(this.left + left, this.top + top - height, width, height);
}
}
}
class BarcodeWidget extends StatelessWidget {
BarcodeWidget({
@required this.data,
this.type = BarcodeType.Code39,
this.color = PdfColors.black,
this.backgroundColor,
this.decoration,
this.margin,
this.padding,
this.width,
this.height,
this.drawText = true,
this.textStyle,
});
/// the barcode data
final String data;
final BarcodeType type;
final PdfColor color;
final PdfColor backgroundColor;
final EdgeInsets padding;
final EdgeInsets margin;
final double width;
final double height;
final bool drawText;
final TextStyle textStyle;
final BoxDecoration decoration;
@override
Widget build(Context context) {
final TextStyle _textStyle = textStyle ?? TextStyle(font: Font.courier());
Widget barcode = _BarcodeWidget(
data: data,
color: color,
barcode: Barcode.fromType(
type: type,
draw: _BarcodeDraw(),
),
);
if (drawText) {
barcode = Column(
children: <Widget>[
Flexible(child: barcode),
Text(
data,
style: _textStyle,
textAlign: TextAlign.center,
softWrap: false,
),
],
);
}
if (padding != null) {
barcode = Padding(padding: padding, child: barcode);
}
if (decoration != null) {
barcode = DecoratedBox(
decoration: decoration,
child: barcode,
);
} else if (backgroundColor != null) {
barcode = DecoratedBox(
decoration: BoxDecoration(color: backgroundColor),
child: barcode,
);
}
if (width != null || height != null) {
barcode = SizedBox(width: width, height: height, child: barcode);
}
if (margin != null) {
barcode = Padding(padding: margin, child: barcode);
}
return barcode;
}
}
... ...
/*
* Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ignore_for_file: omit_local_variable_types
part of widget;
typedef QrError = void Function(dynamic error);
class _QrCodeWidget extends Widget {
_QrCodeWidget({
@required String data,
this.version,
this.errorCorrectionLevel,
this.color,
this.onError,
this.gapless = false,
}) : assert(data != null),
_qr = version == null
? QrCode.fromData(
data: data,
errorCorrectLevel: errorCorrectionLevel,
)
: QrCode(
version,
errorCorrectionLevel,
) {
// configure and make the QR code data
try {
if (version != null) {
_qr.addData(data);
}
_qr.make();
} catch (ex) {
if (onError != null) {
_hasError = true;
onError(ex);
}
}
}
@override
void layout(Context context, BoxConstraints constraints,
{bool parentUsesSize = false}) {
box = PdfRect.fromPoints(PdfPoint.zero, constraints.biggest);
}
/// the qr code version
final int version;
/// the qr code error correction level
final int errorCorrectionLevel;
/// the color of the dark squares
final PdfColor color;
final QrError onError;
final bool gapless;
// our qr code data
final QrCode _qr;
bool _hasError = false;
@override
void paint(Context context) {
super.paint(context);
if (_hasError) {
return;
}
final double shortestSide = box.width < box.height ? box.width : box.height;
assert(shortestSide > 0);
context.canvas.setFillColor(color);
final double squareSize = shortestSide / _qr.moduleCount.toDouble();
final int pxAdjustValue = gapless ? 1 : 0;
for (int x = 0; x < _qr.moduleCount; x++) {
for (int y = 0; y < _qr.moduleCount; y++) {
if (_qr.isDark(y, x)) {
context.canvas.drawRect(
box.left + x * squareSize,
box.top - (y + 1) * squareSize,
squareSize + pxAdjustValue,
squareSize + pxAdjustValue,
);
}
}
}
context.canvas.fillPath();
}
}
class QrCodeWidget extends StatelessWidget {
QrCodeWidget({
@required this.data,
this.version,
this.errorCorrectionLevel = QrErrorCorrectLevel.L,
this.color = PdfColors.black,
this.backgroundColor,
this.decoration,
this.margin,
this.onError,
this.gapless = false,
this.size,
this.padding,
});
/// the qr code data
final String data;
/// the qr code version
final int version;
/// the qr code error correction level
final int errorCorrectionLevel;
/// the color of the dark squares
final PdfColor color;
final PdfColor backgroundColor;
final EdgeInsets margin;
final QrError onError;
final bool gapless;
final double size;
final EdgeInsets padding;
final BoxDecoration decoration;
@override
Widget build(Context context) {
Widget qrcode = AspectRatio(
aspectRatio: 1.0,
child: _QrCodeWidget(
data: data,
version: version,
errorCorrectionLevel: errorCorrectionLevel,
color: color,
onError: onError,
gapless: gapless,
));
if (padding != null) {
qrcode = Padding(padding: padding, child: qrcode);
}
if (decoration != null) {
qrcode = DecoratedBox(
decoration: decoration,
child: qrcode,
);
} else if (backgroundColor != null) {
qrcode = DecoratedBox(
decoration: BoxDecoration(color: backgroundColor),
child: qrcode,
);
}
if (size != null) {
qrcode = SizedBox(width: size, height: size, child: qrcode);
}
if (margin != null) {
qrcode = Padding(padding: margin, child: qrcode);
}
return qrcode;
}
}
... ...
... ... @@ -4,7 +4,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl
homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf
repository: https://github.com/DavBfr/dart_pdf
issue_tracker: https://github.com/DavBfr/dart_pdf/issues
version: 1.3.27
version: 1.3.28
environment:
sdk: ">=2.3.0 <3.0.0"
... ... @@ -15,6 +15,8 @@ dependencies:
utf: ^0.9.0
crypto: ^2.0.6
archive: ^2.0.10
qr: ^1.2.0
barcode: ^0.1.0
dev_dependencies:
test:
... ...
... ... @@ -28,6 +28,7 @@ import 'orientation_test.dart' as orientation;
import 'roll_paper_test.dart' as roll;
import 'ttf_test.dart' as ttf;
import 'type1_test.dart' as type1;
import 'widget_barcode_test.dart' as widget_barcode;
import 'widget_basic_test.dart' as widget_basic;
import 'widget_clip_test.dart' as widget_clip;
import 'widget_container_test.dart' as widget_container;
... ... @@ -54,6 +55,7 @@ void main() {
ttf.main();
type1.main();
widget_basic.main();
widget_barcode.main();
widget_clip.main();
widget_container.main();
widget_flex.main();
... ...
/*
* Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ignore_for_file: omit_local_variable_types
import 'dart:io';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
import 'package:test/test.dart';
Document pdf;
void main() {
setUpAll(() {
Document.debug = true;
pdf = Document();
});
test('Barcode Widgets Code39', () {
pdf.addPage(
Page(
build: (Context context) => BarcodeWidget(
data: 'HELLO 123',
width: 200,
height: 50,
),
),
);
});
test('QrCode Widgets', () {
pdf.addPage(
Page(
build: (Context context) => QrCodeWidget(
data: 'HELLO 123',
size: 200,
padding: const EdgeInsets.all(20),
margin: const EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: 20,
color: PdfColors.white,
border: BoxBorder(
color: PdfColors.blue,
top: true,
bottom: true,
left: true,
right: true,
)),
),
),
);
});
tearDownAll(() {
final File file = File('widgets-barcode.pdf');
file.writeAsBytesSync(pdf.save());
});
}
... ...
import 'package:meta/meta.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
import 'package:qr/qr.dart';
const PdfColor green = PdfColor.fromInt(0xff9ce5d0);
const PdfColor lightGreen = PdfColor.fromInt(0xffcdf1e7);
... ... @@ -109,152 +108,6 @@ class Category extends StatelessWidget {
}
}
typedef QrError = void Function(dynamic error);
class _QrCodeWidget extends Widget {
_QrCodeWidget({
@required String data,
this.version,
this.errorCorrectionLevel,
this.color,
this.onError,
this.gapless = false,
}) : assert(data != null),
_qr = version == null
? QrCode.fromData(
data: data,
errorCorrectLevel: errorCorrectionLevel,
)
: QrCode(
version,
errorCorrectionLevel,
) {
// configure and make the QR code data
try {
if (version != null) {
_qr.addData(data);
}
_qr.make();
} catch (ex) {
if (onError != null) {
_hasError = true;
onError(ex);
}
}
}
@override
void layout(Context context, BoxConstraints constraints,
{bool parentUsesSize = false}) {
box = PdfRect.fromPoints(PdfPoint.zero, constraints.biggest);
}
/// the qr code version
final int version;
/// the qr code error correction level
final int errorCorrectionLevel;
/// the color of the dark squares
final PdfColor color;
final QrError onError;
final bool gapless;
// our qr code data
final QrCode _qr;
bool _hasError = false;
@override
void paint(Context context) {
super.paint(context);
if (_hasError) {
return;
}
final double shortestSide = box.width < box.height ? box.width : box.height;
assert(shortestSide > 0);
context.canvas.setFillColor(color);
final double squareSize = shortestSide / _qr.moduleCount.toDouble();
final int pxAdjustValue = gapless ? 1 : 0;
for (int x = 0; x < _qr.moduleCount; x++) {
for (int y = 0; y < _qr.moduleCount; y++) {
if (_qr.isDark(y, x)) {
context.canvas.drawRect(
box.left + x * squareSize,
box.top - (y + 1) * squareSize,
squareSize + pxAdjustValue,
squareSize + pxAdjustValue,
);
}
}
}
context.canvas.fillPath();
}
}
class QrCodeWidget extends StatelessWidget {
QrCodeWidget({
@required this.data,
this.version,
this.errorCorrectionLevel = QrErrorCorrectLevel.L,
this.color = PdfColors.black,
this.onError,
this.gapless = false,
this.size,
this.padding,
});
/// the qr code data
final String data;
/// the qr code version
final int version;
/// the qr code error correction level
final int errorCorrectionLevel;
/// the color of the dark squares
final PdfColor color;
final QrError onError;
final bool gapless;
final double size;
final EdgeInsets padding;
@override
Widget build(Context context) {
Widget qrcode = AspectRatio(
aspectRatio: 1.0,
child: _QrCodeWidget(
data: data,
version: version,
errorCorrectionLevel: errorCorrectionLevel,
color: color,
onError: onError,
gapless: gapless,
));
if (padding != null) {
qrcode = Padding(padding: padding, child: qrcode);
}
if (size != null) {
qrcode = SizedBox(width: size, height: size, child: qrcode);
}
return qrcode;
}
}
class Percent extends StatelessWidget {
Percent({
@required this.size,
... ...
... ... @@ -13,7 +13,6 @@ dependencies:
path_provider:
flutter_full_pdf_viewer:
cupertino_icons:
qr:
markdown:
dev_dependencies:
... ...