David PHAM-VAN

Opt-in null-safety

Showing 70 changed files with 1009 additions and 1181 deletions

Too many changes to show.

To preserve performance only 70 of 70+ files are displayed.

... ... @@ -12,6 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
FLUTTER?=$(realpath $(dir $(realpath $(dir $(shell which flutter)))))
FLUTTER_BIN=$(FLUTTER)/bin/flutter
DART_BIN=$(FLUTTER)/bin/dart
DART_SRC=$(shell find . -name '*.dart')
CLNG_SRC=$(shell find printing/ios printing/macos printing/windows printing/linux printing/android -name '*.cpp' -o -name '*.cc' -o -name '*.m' -o -name '*.h' -o -name '*.java')
SWFT_SRC=$(shell find printing/ios printing/macos -name '*.swift')
... ... @@ -70,7 +73,7 @@ pdf/hacen-tunisia.ttf:
format: format-dart format-clang format-swift
format-dart: $(DART_SRC)
dart format --fix $^
$(DART_BIN) format --fix $^
format-clang: $(CLNG_SRC)
clang-format -style=Chromium -i $^
... ... @@ -86,38 +89,38 @@ node_modules:
npm install lcov-summary
printing/example/.metadata:
cd printing/example; flutter create -t app --no-overwrite --org net.nfet --project-name example .
cd printing/example; $(FLUTTER_BIN) create -t app --no-overwrite --org net.nfet --project-name example .
rm -rf printing/example/test printing/example/integration_test
pdf/pubspec.lock: pdf/pubspec.yaml
cd pdf; dart pub get
cd pdf; $(DART_BIN) pub get
printing/pubspec.lock: printing/pubspec.yaml
cd printing; flutter packages get
cd printing; $(FLUTTER_BIN) pub get
demo/pubspec.lock: demo/pubspec.yaml
cd demo; flutter packages get
cd demo; $(FLUTTER_BIN) pub get
test/pubspec.lock: test/pubspec.yaml
cd test; flutter packages get
cd test; $(FLUTTER_BIN) pub get
get: $(FONTS) pdf/pubspec.lock printing/pubspec.lock demo/pubspec.lock test/pubspec.lock
test-pdf: svg $(FONTS) pdf/pubspec.lock .coverage
cd pdf; pub global run coverage:collect_coverage --port=$(COV_PORT) -o coverage.json --resume-isolates --wait-paused &\
dart --enable-asserts --disable-service-auth-codes --enable-vm-service=$(COV_PORT) --pause-isolates-on-exit test/all_tests.dart
cd pdf; pub global run coverage:format_coverage --packages=.packages -i coverage.json --report-on lib --lcov --out lcov.info
cd pdf; for EXAMPLE in $(shell cd pdf; find example -name '*.dart'); do dart $$EXAMPLE; done
cd pdf; $(DART_BIN) pub global run coverage:collect_coverage --port=$(COV_PORT) -o coverage.json --resume-isolates --wait-paused &\
$(DART_BIN) --enable-asserts --disable-service-auth-codes --enable-vm-service=$(COV_PORT) --pause-isolates-on-exit test/all_tests.dart
cd pdf; $(DART_BIN) pub global run coverage:format_coverage --packages=.packages -i coverage.json --report-on lib --lcov --out lcov.info
cd pdf; for EXAMPLE in $(shell cd pdf; find example -name '*.dart'); do $(DART_BIN) $$EXAMPLE; done
test/compare-pdf.sh pdf test/golden
test-printing: $(FONTS) printing/pubspec.lock .coverage
cd printing; flutter test --coverage --coverage-path lcov.info
cd printing; $(FLUTTER_BIN) test --coverage --coverage-path lcov.info
test-demo: $(FONTS) demo/pubspec.lock .coverage
cd demo; flutter test --coverage --coverage-path lcov.info
cd demo; $(FLUTTER_BIN) test --coverage --coverage-path lcov.info
test-readme: $(FONTS) test/pubspec.lock
cd test; dart extract_readme.dart
cd test; $(DART_BIN) extract_readme.dart
cd test; dartanalyzer readme-*.dart
test: test-pdf test-printing test-demo node_modules
... ... @@ -129,40 +132,40 @@ clean:
publish-pdf: format clean
test -z "$(shell git status --porcelain)"
find pdf -name pubspec.yaml -exec sed -i -e 's/^dependency_overrides:/_dependency_overrides:/g' '{}' ';'
cd pdf; dart pub publish -f
cd pdf; $(DART_BIN) pub publish -f
find pdf -name pubspec.yaml -exec sed -i -e 's/^_dependency_overrides:/dependency_overrides:/g' '{}' ';'
git tag $(shell grep version pdf/pubspec.yaml | sed 's/version\s*:\s*/pdf-/g')
publish-printing: format clean
test -z "$(shell git status --porcelain)"
find printing -name pubspec.yaml -exec sed -i -e 's/^dependency_overrides:/_dependency_overrides:/g' '{}' ';'
cd printing; dart pub publish -f
cd printing; $(DART_BIN) pub publish -f
find printing -name pubspec.yaml -exec sed -i -e 's/^_dependency_overrides:/dependency_overrides:/g' '{}' ';'
git tag $(shell grep version printing/pubspec.yaml | sed 's/version\s*:\s*/printing-/g')
.pana:
which pana || dart pub global activate pana
which pana || $(DART_BIN) pub global activate pana
touch $@
analyze-pdf: .pana
@find pdf -name pubspec.yaml -exec sed -i -e 's/^dependency_overrides:/_dependency_overrides:/g' '{}' ';'
@dart pub global run pana --no-warning --source path pdf
@find pdf -name pubspec.yaml -exec sed -i -e 's/^_dependency_overrides:/dependency_overrides:/g' '{}' ';'
find pdf -name pubspec.yaml -exec sed -i -e 's/^dependency_overrides:/_dependency_overrides:/g' '{}' ';'
$(DART_BIN) pub global run pana --no-warning --source path pdf
find pdf -name pubspec.yaml -exec sed -i -e 's/^_dependency_overrides:/dependency_overrides:/g' '{}' ';'
analyze-printing: .pana
@find printing -name pubspec.yaml -exec sed -i -e 's/^dependency_overrides:/_dependency_overrides:/g' '{}' ';'
@dart pub global run pana --no-warning --source path printing
@find printing -name pubspec.yaml -exec sed -i -e 's/^_dependency_overrides:/dependency_overrides:/g' '{}' ';'
find printing -name pubspec.yaml -exec sed -i -e 's/^dependency_overrides:/_dependency_overrides:/g' '{}' ';'
$(DART_BIN) pub global run pana --no-warning --source path printing
find printing -name pubspec.yaml -exec sed -i -e 's/^_dependency_overrides:/dependency_overrides:/g' '{}' ';'
analyze: analyze-pdf analyze-printing
.dartfix:
which dartfix || dart pub global activate dartfix
which dartfix || $(DART_BIN) pub global activate dartfix
touch $@
fix: get .dartfix
cd pdf; dart pub global run dartfix --pedantic --overwrite .
cd printing; dart pub global run dartfix --pedantic --overwrite .
cd pdf; $(DART_BIN) pub global run dartfix --pedantic --overwrite .
cd printing; $(DART_BIN) pub global run dartfix --pedantic --overwrite .
ref/svg/%.svg:
mkdir -p ref/svg
... ... @@ -257,7 +260,7 @@ ref: svg
cd $@; curl -OL 'https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf'
gh-pages: all
cd demo; flutter build web
cd demo; $(FLUTTER_BIN) build web
git checkout gh-pages
rm -rf assets icons
mv -fv demo/build/web/* .
... ...
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
... ...
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
... ...
/*
* 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.
*/
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart';
import 'package:url_launcher/url_launcher.dart' as ul;
import 'calendar.dart';
import 'document.dart';
import 'invoice.dart';
import 'report.dart';
import 'resume.dart';
class MyApp extends StatefulWidget {
@override
MyAppState createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
List<Tab>? _myTabs;
List<LayoutCallback>? _tabGen;
List<String>? _tabUrl;
int _tab = 0;
TabController? _tabController;
PrintingInfo? printingInfo;
@override
void initState() {
super.initState();
_init();
}
Future<void> _init() async {
final info = await Printing.info();
_myTabs = const <Tab>[
Tab(text: 'RÉSUMÉ'),
Tab(text: 'DOCUMENT'),
Tab(text: 'INVOICE'),
Tab(text: 'REPORT'),
Tab(text: 'CALENDAR'),
];
_tabGen = const <LayoutCallback>[
generateResume,
generateDocument,
generateInvoice,
generateReport,
generateCalendar,
];
_tabUrl = const <String>[
'resume.dart',
'document.dart',
'invoice.dart',
'report.dart',
'calendar.dart',
];
_tabController = TabController(
vsync: this,
length: _myTabs!.length,
initialIndex: _tab,
);
_tabController!.addListener(() {
setState(() {
_tab = _tabController!.index;
});
});
setState(() {
printingInfo = info;
});
}
void _showPrintedToast(BuildContext context) {
final scaffold = Scaffold.of(context);
// ignore: deprecated_member_use
scaffold.showSnackBar(
const SnackBar(
content: Text('Document printed successfully'),
),
);
}
void _showSharedToast(BuildContext context) {
final scaffold = Scaffold.of(context);
// ignore: deprecated_member_use
scaffold.showSnackBar(
const SnackBar(
content: Text('Document shared successfully'),
),
);
}
Future<void> _saveAsFile(
BuildContext context,
LayoutCallback build,
PdfPageFormat pageFormat,
) async {
final bytes = await build(pageFormat);
final appDocDir = await getApplicationDocumentsDirectory();
final appDocPath = appDocDir.path;
final file = File(appDocPath + '/' + 'document.pdf');
print('Save as file ${file.path} ...');
await file.writeAsBytes(bytes);
await OpenFile.open(file.path);
}
@override
Widget build(BuildContext context) {
pw.RichText.debug = true;
if (_tabController == null) {
return const Center(child: CircularProgressIndicator());
}
final actions = <PdfPreviewAction>[
if (!kIsWeb)
PdfPreviewAction(
icon: const Icon(Icons.save),
onPressed: _saveAsFile,
)
];
return Scaffold(
appBar: AppBar(
title: const Text('Pdf Printing Example'),
bottom: TabBar(
controller: _tabController,
tabs: _myTabs!,
),
),
body: PdfPreview(
maxPageWidth: 700,
build: _tabGen![_tab],
actions: actions,
onPrinted: _showPrintedToast,
onShared: _showSharedToast,
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.deepOrange,
onPressed: _showSources,
child: const Icon(Icons.code),
),
);
}
void _showSources() {
ul.launch(
'https://github.com/DavBfr/dart_pdf/blob/master/demo/lib/${_tabUrl![_tab]}',
);
}
}
... ...
... ... @@ -28,11 +28,11 @@ class Calendar extends StatelessWidget {
this.year,
});
final DateTime date;
final DateTime? date;
final int month;
final int? month;
final int year;
final int? year;
Widget title(
Context context,
... ... @@ -178,7 +178,7 @@ Future<Uint8List> generateCalendar(PdfPageFormat pageFormat) async {
//Create a PDF document.
final document = Document();
final date = DateTime.now();
String bg;
String? bg;
switch (date.month) {
case 12:
... ... @@ -198,7 +198,7 @@ Future<Uint8List> generateCalendar(PdfPageFormat pageFormat) async {
buildForeground: bg == null
? null
: (context) =>
FullPage(ignoreMargins: true, child: SvgImage(svg: bg)),
FullPage(ignoreMargins: true, child: SvgImage(svg: bg!)),
),
build: (context) => Padding(
padding: const EdgeInsets.only(right: 20),
... ...
... ... @@ -28,7 +28,7 @@ Future<Uint8List> generateDocument(PdfPageFormat format) async {
crossAxisAlignment: pw.CrossAxisAlignment.start,
header: (pw.Context context) {
if (context.pageNumber == 1) {
return null;
return pw.SizedBox();
}
return pw.Container(
alignment: pw.Alignment.centerRight,
... ... @@ -38,8 +38,7 @@ Future<Uint8List> generateDocument(PdfPageFormat format) async {
border: pw.Border(
bottom: pw.BorderSide(width: 0.5, color: PdfColors.grey))),
child: pw.Text('Portable Document Format',
style: pw.Theme.of(context)
.defaultTextStyle
style: pw.Theme.of(context).defaultTextStyle
.copyWith(color: PdfColors.grey)));
},
footer: (pw.Context context) {
... ... @@ -48,8 +47,7 @@ Future<Uint8List> generateDocument(PdfPageFormat format) async {
margin: const pw.EdgeInsets.only(top: 1.0 * PdfPageFormat.cm),
child: pw.Text(
'Page ${context.pageNumber} of ${context.pagesCount}',
style: pw.Theme.of(context)
.defaultTextStyle
style: pw.Theme.of(context).defaultTextStyle
.copyWith(color: PdfColors.grey)));
},
build: (pw.Context context) => <pw.Widget>[
... ...
... ... @@ -58,14 +58,14 @@ Future<Uint8List> generateInvoice(PdfPageFormat pageFormat) async {
class Invoice {
Invoice({
this.products,
this.customerName,
this.customerAddress,
this.invoiceNumber,
this.tax,
this.paymentInfo,
this.baseColor,
this.accentColor,
required this.products,
required this.customerName,
required this.customerAddress,
required this.invoiceNumber,
required this.tax,
required this.paymentInfo,
required this.baseColor,
required this.accentColor,
});
final List<Product> products;
... ... @@ -91,9 +91,9 @@ class Invoice {
double get _grandTotal => _total * (1 + tax);
String _logo;
String? _logo;
String _bgShape;
String? _bgShape;
Future<Uint8List> buildPdf(PdfPageFormat pageFormat) async {
// Create a PDF document.
... ... @@ -111,9 +111,9 @@ class Invoice {
pw.MultiPage(
pageTheme: _buildTheme(
pageFormat,
font1 != null ? pw.Font.ttf(font1) : null,
font2 != null ? pw.Font.ttf(font2) : null,
font3 != null ? pw.Font.ttf(font3) : null,
pw.Font.ttf(font1),
pw.Font.ttf(font2),
pw.Font.ttf(font3),
),
header: _buildHeader,
footer: _buildFooter,
... ... @@ -192,7 +192,7 @@ class Invoice {
padding: const pw.EdgeInsets.only(bottom: 8, left: 30),
height: 72,
child:
_logo != null ? pw.SvgImage(svg: _logo) : pw.PdfLogo(),
_logo != null ? pw.SvgImage(svg: _logo!) : pw.PdfLogo(),
),
// pw.Container(
// color: baseColor,
... ... @@ -243,7 +243,7 @@ class Invoice {
),
buildBackground: (context) => pw.FullPage(
ignoreMargins: true,
child: pw.SvgImage(svg: _bgShape),
child: pw.SvgImage(svg: _bgShape!),
),
);
}
... ...
... ... @@ -14,173 +14,14 @@
* limitations under the License.
*/
import 'dart:async';
import 'dart:io';
// @dart=2.9
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart';
import 'package:url_launcher/url_launcher.dart' as ul;
import 'calendar.dart';
import 'document.dart';
import 'invoice.dart';
import 'report.dart';
import 'resume.dart';
import 'app.dart';
void main() {
debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia;
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
@override
MyAppState createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
List<Tab> _myTabs;
List<LayoutCallback> _tabGen;
List<String> _tabUrl;
int _tab = 0;
TabController _tabController;
PrintingInfo printingInfo;
@override
void initState() {
super.initState();
_init();
}
Future<void> _init() async {
final info = await Printing.info();
_myTabs = const <Tab>[
Tab(text: 'RÉSUMÉ'),
Tab(text: 'DOCUMENT'),
Tab(text: 'INVOICE'),
Tab(text: 'REPORT'),
Tab(text: 'CALENDAR'),
];
_tabGen = const <LayoutCallback>[
generateResume,
generateDocument,
generateInvoice,
generateReport,
generateCalendar,
];
_tabUrl = const <String>[
'resume.dart',
'document.dart',
'invoice.dart',
'report.dart',
'calendar.dart',
];
_tabController = TabController(
vsync: this,
length: _myTabs.length,
initialIndex: _tab,
);
_tabController.addListener(() {
setState(() {
_tab = _tabController.index;
});
});
setState(() {
printingInfo = info;
});
}
void _showPrintedToast(BuildContext context) {
final scaffold = Scaffold.of(context);
// ignore: deprecated_member_use
scaffold.showSnackBar(
const SnackBar(
content: Text('Document printed successfully'),
),
);
}
void _showSharedToast(BuildContext context) {
final scaffold = Scaffold.of(context);
// ignore: deprecated_member_use
scaffold.showSnackBar(
const SnackBar(
content: Text('Document shared successfully'),
),
);
}
Future<void> _saveAsFile(
BuildContext context,
LayoutCallback build,
PdfPageFormat pageFormat,
) async {
final bytes = await build(pageFormat);
final appDocDir = await getApplicationDocumentsDirectory();
final appDocPath = appDocDir.path;
final file = File(appDocPath + '/' + 'document.pdf');
print('Save as file ${file.path} ...');
await file.writeAsBytes(bytes);
await OpenFile.open(file.path);
}
@override
Widget build(BuildContext context) {
pw.RichText.debug = true;
if (_tabController == null) {
return const Center(child: CircularProgressIndicator());
}
final actions = <PdfPreviewAction>[
if (!kIsWeb)
PdfPreviewAction(
icon: const Icon(Icons.save),
onPressed: _saveAsFile,
)
];
return Scaffold(
appBar: AppBar(
title: const Text('Pdf Printing Example'),
bottom: TabBar(
controller: _tabController,
tabs: _myTabs,
),
),
body: PdfPreview(
maxPageWidth: 700,
build: _tabGen[_tab],
actions: actions,
onPrinted: _showPrintedToast,
onShared: _showSharedToast,
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.deepOrange,
onPressed: _showSources,
child: const Icon(Icons.code),
),
);
}
void _showSources() {
ul.launch(
'https://github.com/DavBfr/dart_pdf/blob/master/demo/lib/${_tabUrl[_tab]}',
);
}
}
... ...
... ... @@ -70,7 +70,9 @@ Future<Uint8List> generateReport(PdfPageFormat pageFormat) async {
grid: pw.CartesianGrid(
xAxis: pw.FixedAxis.fromStrings(
List<String>.generate(
dataTable.length, (index) => dataTable[index][0]),
dataTable.length,
// ignore: avoid_as
(index) => dataTable[index][0] as String),
marginStart: 30,
marginEnd: 30,
ticks: true,
... ... @@ -91,7 +93,8 @@ Future<Uint8List> generateReport(PdfPageFormat pageFormat) async {
data: List<pw.LineChartValue>.generate(
dataTable.length,
(i) {
final num v = dataTable[i][2];
// ignore: avoid_as
final v = dataTable[i][2] as num;
return pw.LineChartValue(i.toDouble(), v.toDouble());
},
),
... ... @@ -105,7 +108,8 @@ Future<Uint8List> generateReport(PdfPageFormat pageFormat) async {
data: List<pw.LineChartValue>.generate(
dataTable.length,
(i) {
final num v = dataTable[i][1];
// ignore: avoid_as
final v = dataTable[i][1] as num;
return pw.LineChartValue(i.toDouble(), v.toDouble());
},
),
... ... @@ -130,7 +134,8 @@ Future<Uint8List> generateReport(PdfPageFormat pageFormat) async {
data: List<pw.LineChartValue>.generate(
dataTable.length,
(i) {
final num v = dataTable[i][2];
// ignore: avoid_as
final v = dataTable[i][2] as num;
return pw.LineChartValue(i.toDouble(), v.toDouble());
},
),
... ...
... ... @@ -18,9 +18,7 @@ import 'dart:async';
import 'dart:math';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:meta/meta.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
... ... @@ -196,11 +194,14 @@ Future<pw.PageTheme> _myPageTheme(PdfPageFormat format) async {
}
class _Block extends pw.StatelessWidget {
_Block({this.title, this.icon});
_Block({
required this.title,
this.icon,
});
final String title;
final pw.IconData icon;
final pw.IconData? icon;
@override
pw.Widget build(pw.Context context) {
... ... @@ -222,7 +223,7 @@ class _Block extends pw.StatelessWidget {
.defaultTextStyle
.copyWith(fontWeight: pw.FontWeight.bold)),
pw.Spacer(),
if (icon != null) pw.Icon(icon, color: lightGreen, size: 18),
if (icon != null) pw.Icon(icon!, color: lightGreen, size: 18),
]),
pw.Container(
decoration: const pw.BoxDecoration(
... ... @@ -240,7 +241,7 @@ class _Block extends pw.StatelessWidget {
}
class _Category extends pw.StatelessWidget {
_Category({this.title});
_Category({required this.title});
final String title;
... ... @@ -259,14 +260,14 @@ class _Category extends pw.StatelessWidget {
class _Percent extends pw.StatelessWidget {
_Percent({
@required this.size,
@required this.value,
this.title,
required this.size,
required this.value,
required this.title,
this.fontSize = 1.2,
this.color = green,
this.backgroundColor = PdfColors.grey300,
this.strokeWidth = 5,
}) : assert(size != null);
});
final double size;
... ... @@ -309,9 +310,7 @@ class _Percent extends pw.StatelessWidget {
)
];
if (title != null) {
widgets.add(title);
}
widgets.add(title);
return pw.Column(children: widgets);
}
... ...
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
... ...
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "ephemeral/Flutter-Generated.xcconfig"
... ...
... ... @@ -9,74 +9,32 @@ project 'Runner', {
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
end
pods_ary = []
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) { |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_ary.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_ary
end
def pubspec_supports_macos(file)
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return false;
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
File.foreach(file_abs_path) { |line|
return true if line =~ /^\s*macos:/
}
return false
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_macos_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
ephemeral_dir = File.join('Flutter', 'ephemeral')
symlink_dir = File.join(ephemeral_dir, '.symlinks')
symlink_plugins_dir = File.join(symlink_dir, 'plugins')
system("rm -rf #{symlink_dir}")
system("mkdir -p #{symlink_plugins_dir}")
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
end
# Flutter Pods
generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig'))
if generated_xcconfig.empty?
puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target)
end
generated_xcconfig.map { |p|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
symlink = File.join(symlink_dir, 'flutter')
File.symlink(File.dirname(p[:path]), symlink)
pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path]))
end
}
# Plugin Pods
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.map { |p|
symlink = File.join(symlink_plugins_dir, p[:name])
File.symlink(p[:path], symlink)
if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml'))
pod p[:name], :path => File.join(symlink, 'macos')
end
}
end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true
... ...
... ... @@ -26,11 +26,7 @@
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; };
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
431DC00351DB0DC4ABC58D3B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 965F29CC9777229324768DEB /* Pods_Runner.framework */; };
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; };
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
... ... @@ -50,8 +46,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */,
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */,
);
name = "Bundle Framework";
runOnlyForDeploymentPostprocessing = 0;
... ... @@ -70,7 +64,6 @@
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = "<group>"; };
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = "<group>"; };
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = "<group>"; };
33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; };
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
... ... @@ -80,7 +73,6 @@
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
AD2199B14072A81AC81343D7 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
C23983A634DCC94446D395FD /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
... ... @@ -88,8 +80,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */,
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */,
431DC00351DB0DC4ABC58D3B /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
... ... @@ -145,8 +135,6 @@
33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */,
33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */,
33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */,
D73912EF22F37F9E000D13A0 /* App.framework */,
33D1A10322148B71006C7A3E /* FlutterMacOS.framework */,
);
path = Flutter;
sourceTree = "<group>";
... ... @@ -281,7 +269,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n";
shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n";
};
33CC111E2044C6BF0003C045 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
... ... @@ -331,9 +319,11 @@
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
... ...
... ... @@ -4,20 +4,19 @@ description: Pdf Printing Demo
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
sdk: '>=2.12.0-224.0.dev <3.0.0'
flutter: ">=1.26.0-17.1.pre <2.0.0"
dependencies:
flutter:
sdk: flutter
intl:
intl: ^0.17.0-nullsafety
open_file:
path_provider:
printing:
url_launcher:
url_launcher: ^6.0.0-nullsafety
dev_dependencies:
flutter_driver:
sdk: flutter
flutter_test:
sdk: flutter
test:
... ...
/*
* 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.
*/
import 'package:flutter_driver/driver_extension.dart';
import 'package:printing_demo/main.dart' as app;
void main() {
// Enables flutter_driver extension
enableFlutterDriverExtension();
// Call the `main()` function of the app
app.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.
*/
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
void main() {
group('wrapWidget integration tests', () {
FlutterDriver driver;
final screenshotFinder = find.byValueKey('screenshot');
setUpAll(() async {
driver = await FlutterDriver.connect();
});
tearDownAll(() {
if (driver != null) {
driver.close();
}
});
test('renders Widget as Image', () async {
await driver.tap(screenshotFinder);
});
});
}
# Changelog
## 2.1.0
## 3.0.0-nullsafety.0
- Fix SVG fit alignment
- Add DecorationSvgImage
- Opt-In null-safety
## 2.0.0
... ...
... ... @@ -7,7 +7,7 @@ Future<void> main() async {
pdf.addPage(
pw.Page(
build: (pw.Context context) => pw.Center(
build: (pw.Context? context) => pw.Center(
child: pw.Text('Hello World!'),
),
),
... ...
... ... @@ -32,8 +32,7 @@ import 'stream.dart';
class PdfAnnot extends PdfObject {
PdfAnnot(this.pdfPage, this.annot)
: assert(annot != null),
super(pdfPage.pdfDocument, type: '/Annot') {
: super(pdfPage.pdfDocument, type: '/Annot') {
pdfPage.annotations.add(this);
}
... ... @@ -91,16 +90,15 @@ enum PdfAnnotApparence {
abstract class PdfAnnotBase {
PdfAnnotBase({
@required this.subtype,
@required this.rect,
required this.subtype,
required this.rect,
this.border,
this.content,
this.name,
this.flags,
this.date,
this.color,
}) : assert(subtype != null),
assert(rect != null);
});
/// The subtype of the outline, ie text, note, etc
final String subtype;
... ... @@ -108,31 +106,31 @@ abstract class PdfAnnotBase {
final PdfRect rect;
/// the border for this annotation
final PdfBorder border;
final PdfBorder? border;
/// The text of a text annotation
final String content;
final String? content;
/// The internal name for a link
final String name;
final String? name;
/// Flags specifying various characteristics of the annotation
final Set<PdfAnnotFlags> flags;
final Set<PdfAnnotFlags>? flags;
/// Last modification date
final DateTime date;
final DateTime? date;
/// Color
final PdfColor color;
final PdfColor? color;
final Map<String, PdfDataType> _appearances = <String, PdfDataType>{};
final Map<String?, PdfDataType> _appearances = <String?, PdfDataType>{};
int get flagValue {
if (flags == null || flags.isEmpty) {
if (flags == null || flags!.isEmpty) {
return 0;
}
return flags
return flags!
.map<int>((PdfAnnotFlags e) => 1 << e.index)
.reduce((int a, int b) => a | b);
}
... ... @@ -140,12 +138,12 @@ abstract class PdfAnnotBase {
PdfGraphics appearance(
PdfDocument pdfDocument,
PdfAnnotApparence type, {
String name,
Matrix4 matrix,
PdfRect boundingBox,
String? name,
Matrix4? matrix,
PdfRect? boundingBox,
}) {
final s = PdfGraphicXObject(pdfDocument, '/Form');
String n;
String? n;
switch (type) {
case PdfAnnotApparence.normal:
n = '/N';
... ... @@ -163,8 +161,10 @@ abstract class PdfAnnotBase {
if (_appearances[n] is! PdfDict) {
_appearances[n] = PdfDict();
}
final PdfDict d = _appearances[n];
d[name] = s.ref();
final d = _appearances[n];
if (d is PdfDict) {
d[name] = s.ref();
}
}
if (matrix != null) {
... ... @@ -180,7 +180,7 @@ abstract class PdfAnnotBase {
final bbox = boundingBox ?? PdfRect.fromPoints(PdfPoint.zero, rect.size);
s.params['/BBox'] =
PdfArray.fromNum(<double>[bbox.x, bbox.y, bbox.width, bbox.height]);
PdfArray.fromNum(<double?>[bbox.x, bbox.y, bbox.width, bbox.height]);
final g = PdfGraphics(s, s.buf);
return g;
}
... ... @@ -190,7 +190,7 @@ abstract class PdfAnnotBase {
void build(PdfPage page, PdfObject object, PdfDict params) {
params['/Subtype'] = PdfName(subtype);
params['/Rect'] = PdfArray.fromNum(
<double>[rect.left, rect.bottom, rect.right, rect.top]);
<double?>[rect.left, rect.bottom, rect.right, rect.top]);
params['/P'] = page.ref();
... ... @@ -198,34 +198,36 @@ abstract class PdfAnnotBase {
if (border == null) {
params['/Border'] = PdfArray.fromNum(const <int>[0, 0, 0]);
} else {
params['/BS'] = border.ref();
params['/BS'] = border!.ref();
}
if (content != null) {
params['/Contents'] = PdfSecString.fromString(object, content);
params['/Contents'] = PdfSecString.fromString(object, content!);
}
if (name != null) {
params['/NM'] = PdfSecString.fromString(object, name);
params['/NM'] = PdfSecString.fromString(object, name!);
}
if (flags != null && flags.isNotEmpty) {
if (flags != null && flags!.isNotEmpty) {
params['/F'] = PdfNum(flagValue);
}
if (date != null) {
params['/M'] = PdfSecString.fromDate(object, date);
params['/M'] = PdfSecString.fromDate(object, date!);
}
if (color != null) {
params['/C'] = PdfColorType(color);
params['/C'] = PdfColorType(color!);
}
if (_appearances.isNotEmpty) {
params['/AP'] = PdfDict(_appearances);
if (_appearances['/N'] is PdfDict) {
final PdfDict n = _appearances['/N'];
params['/AS'] = PdfName(n.values.keys.first);
final n = _appearances['/N'];
if (n is PdfDict) {
params['/AS'] = PdfName(n.values.keys.first!);
}
}
}
}
... ... @@ -234,16 +236,14 @@ abstract class PdfAnnotBase {
class PdfAnnotText extends PdfAnnotBase {
/// Create a text annotation
PdfAnnotText({
@required PdfRect rect,
@required String content,
PdfBorder border,
String name,
Set<PdfAnnotFlags> flags,
DateTime date,
PdfColor color,
}) : assert(rect != null),
assert(content != null),
super(
required PdfRect rect,
required String content,
PdfBorder? border,
String? name,
Set<PdfAnnotFlags>? flags,
DateTime? date,
PdfColor? color,
}) : super(
subtype: '/Text',
rect: rect,
border: border,
... ... @@ -258,12 +258,12 @@ class PdfAnnotText extends PdfAnnotBase {
class PdfAnnotNamedLink extends PdfAnnotBase {
/// Create a named link annotation
PdfAnnotNamedLink({
@required PdfRect rect,
@required this.dest,
PdfBorder border,
Set<PdfAnnotFlags> flags,
DateTime date,
PdfColor color,
required PdfRect rect,
required this.dest,
PdfBorder? border,
Set<PdfAnnotFlags>? flags,
DateTime? date,
PdfColor? color,
}) : super(
subtype: '/Link',
rect: rect,
... ... @@ -290,15 +290,13 @@ class PdfAnnotNamedLink extends PdfAnnotBase {
class PdfAnnotUrlLink extends PdfAnnotBase {
/// Create an url link annotation
PdfAnnotUrlLink({
@required PdfRect rect,
@required this.url,
PdfBorder border,
Set<PdfAnnotFlags> flags,
DateTime date,
PdfColor color,
}) : assert(rect != null),
assert(url != null),
super(
required PdfRect rect,
required this.url,
PdfBorder? border,
Set<PdfAnnotFlags>? flags,
DateTime? date,
PdfColor? color,
}) : super(
subtype: '/Link',
rect: rect,
border: border,
... ... @@ -326,18 +324,16 @@ enum PdfAnnotHighlighting { none, invert, outline, push, toggle }
abstract class PdfAnnotWidget extends PdfAnnotBase {
/// Create a widget annotation
PdfAnnotWidget({
@required PdfRect rect,
@required this.fieldType,
required PdfRect rect,
required this.fieldType,
this.fieldName,
PdfBorder border,
Set<PdfAnnotFlags> flags,
DateTime date,
PdfColor color,
PdfBorder? border,
Set<PdfAnnotFlags>? flags,
DateTime? date,
PdfColor? color,
this.backgroundColor,
this.highlighting,
}) : assert(rect != null),
assert(fieldType != null),
super(
}) : super(
subtype: '/Widget',
rect: rect,
border: border,
... ... @@ -348,11 +344,11 @@ abstract class PdfAnnotWidget extends PdfAnnotBase {
final String fieldType;
final String fieldName;
final String? fieldName;
final PdfAnnotHighlighting highlighting;
final PdfAnnotHighlighting? highlighting;
final PdfColor backgroundColor;
final PdfColor? backgroundColor;
@override
void build(PdfPage page, PdfObject object, PdfDict params) {
... ... @@ -361,16 +357,16 @@ abstract class PdfAnnotWidget extends PdfAnnotBase {
params['/FT'] = PdfName(fieldType);
if (fieldName != null) {
params['/T'] = PdfSecString.fromString(object, fieldName);
params['/T'] = PdfSecString.fromString(object, fieldName!);
}
final mk = PdfDict();
if (color != null) {
mk.values['/BC'] = PdfColorType(color);
mk.values['/BC'] = PdfColorType(color!);
}
if (backgroundColor != null) {
mk.values['/BG'] = PdfColorType(backgroundColor);
mk.values['/BG'] = PdfColorType(backgroundColor!);
}
if (mk.values.isNotEmpty) {
... ... @@ -378,7 +374,7 @@ abstract class PdfAnnotWidget extends PdfAnnotBase {
}
if (highlighting != null) {
switch (highlighting) {
switch (highlighting!) {
case PdfAnnotHighlighting.none:
params['/H'] = const PdfName('/N');
break;
... ... @@ -401,15 +397,14 @@ abstract class PdfAnnotWidget extends PdfAnnotBase {
class PdfAnnotSign extends PdfAnnotWidget {
PdfAnnotSign({
@required PdfRect rect,
String fieldName,
PdfBorder border,
Set<PdfAnnotFlags> flags,
DateTime date,
PdfColor color,
PdfAnnotHighlighting highlighting,
}) : assert(rect != null),
super(
required PdfRect rect,
String? fieldName,
PdfBorder? border,
Set<PdfAnnotFlags>? flags,
DateTime? date,
PdfColor? color,
PdfAnnotHighlighting? highlighting,
}) : super(
rect: rect,
fieldType: '/Sig',
fieldName: fieldName,
... ... @@ -424,7 +419,7 @@ class PdfAnnotSign extends PdfAnnotWidget {
void build(PdfPage page, PdfObject object, PdfDict params) {
super.build(page, object, params);
assert(page.pdfDocument.sign != null);
params['/V'] = page.pdfDocument.sign.ref();
params['/V'] = page.pdfDocument.sign!.ref();
}
}
... ... @@ -528,21 +523,19 @@ enum PdfFieldFlags {
class PdfFormField extends PdfAnnotWidget {
PdfFormField({
@required String fieldType,
@required PdfRect rect,
String fieldName,
required String fieldType,
required PdfRect rect,
String? fieldName,
this.alternateName,
this.mappingName,
PdfBorder border,
Set<PdfAnnotFlags> flags,
DateTime date,
PdfColor color,
PdfColor backgroundColor,
PdfAnnotHighlighting highlighting,
PdfBorder? border,
Set<PdfAnnotFlags>? flags,
DateTime? date,
PdfColor? color,
PdfColor? backgroundColor,
PdfAnnotHighlighting? highlighting,
this.fieldFlags,
}) : assert(rect != null),
assert(fieldType != null),
super(
}) : super(
rect: rect,
fieldType: fieldType,
fieldName: fieldName,
... ... @@ -554,18 +547,18 @@ class PdfFormField extends PdfAnnotWidget {
highlighting: highlighting,
);
final String alternateName;
final String? alternateName;
final String mappingName;
final String? mappingName;
final Set<PdfFieldFlags> fieldFlags;
final Set<PdfFieldFlags>? fieldFlags;
int get fieldFlagsValue {
if (fieldFlags == null || fieldFlags.isEmpty) {
if (fieldFlags == null || fieldFlags!.isEmpty) {
return 0;
}
return fieldFlags
return fieldFlags!
.map<int>((PdfFieldFlags e) => 1 << e.index)
.reduce((int a, int b) => a | b);
}
... ... @@ -574,10 +567,10 @@ class PdfFormField extends PdfAnnotWidget {
void build(PdfPage page, PdfObject object, PdfDict params) {
super.build(page, object, params);
if (alternateName != null) {
params['/TU'] = PdfSecString.fromString(object, alternateName);
params['/TU'] = PdfSecString.fromString(object, alternateName!);
}
if (mappingName != null) {
params['/TM'] = PdfSecString.fromString(object, mappingName);
params['/TM'] = PdfSecString.fromString(object, mappingName!);
}
params['/Ff'] = PdfNum(fieldFlagsValue);
... ... @@ -588,29 +581,25 @@ enum PdfTextFieldAlign { left, center, right }
class PdfTextField extends PdfFormField {
PdfTextField({
@required PdfRect rect,
String fieldName,
String alternateName,
String mappingName,
PdfBorder border,
Set<PdfAnnotFlags> flags,
DateTime date,
PdfColor color,
PdfColor backgroundColor,
PdfAnnotHighlighting highlighting,
Set<PdfFieldFlags> fieldFlags,
required PdfRect rect,
String? fieldName,
String? alternateName,
String? mappingName,
PdfBorder? border,
Set<PdfAnnotFlags>? flags,
DateTime? date,
PdfColor? color,
PdfColor? backgroundColor,
PdfAnnotHighlighting? highlighting,
Set<PdfFieldFlags>? fieldFlags,
this.value,
this.defaultValue,
this.maxLength,
@required this.font,
@required this.fontSize,
@required this.textColor,
required this.font,
required this.fontSize,
required this.textColor,
this.textAlign,
}) : assert(rect != null),
assert(fontSize != null),
assert(textColor != null),
assert(font != null),
super(
}) : super(
rect: rect,
fieldType: '/Tx',
fieldName: fieldName,
... ... @@ -625,11 +614,11 @@ class PdfTextField extends PdfFormField {
fieldFlags: fieldFlags,
);
final int maxLength;
final int? maxLength;
final String value;
final String? value;
final String defaultValue;
final String? defaultValue;
final PdfFont font;
... ... @@ -637,13 +626,13 @@ class PdfTextField extends PdfFormField {
final PdfColor textColor;
final PdfTextFieldAlign textAlign;
final PdfTextFieldAlign? textAlign;
@override
void build(PdfPage page, PdfObject object, PdfDict params) {
super.build(page, object, params);
if (maxLength != null) {
params['/MaxLen'] = PdfNum(maxLength);
params['/MaxLen'] = PdfNum(maxLength!);
}
final buf = PdfStream();
... ... @@ -653,34 +642,33 @@ class PdfTextField extends PdfFormField {
params['/DA'] = PdfSecString.fromStream(object, buf);
if (value != null) {
params['/V'] = PdfSecString.fromString(object, value);
params['/V'] = PdfSecString.fromString(object, value!);
}
if (defaultValue != null) {
params['/DV'] = PdfSecString.fromString(object, defaultValue);
params['/DV'] = PdfSecString.fromString(object, defaultValue!);
}
if (textAlign != null) {
params['/Q'] = PdfNum(textAlign.index);
params['/Q'] = PdfNum(textAlign!.index);
}
}
}
class PdfButtonField extends PdfFormField {
PdfButtonField({
@required PdfRect rect,
String fieldName,
String alternateName,
String mappingName,
PdfBorder border,
Set<PdfAnnotFlags> flags,
DateTime date,
PdfColor color,
PdfColor backgroundColor,
PdfAnnotHighlighting highlighting,
Set<PdfFieldFlags> fieldFlags,
required PdfRect rect,
String? fieldName,
String? alternateName,
String? mappingName,
PdfBorder? border,
Set<PdfAnnotFlags>? flags,
DateTime? date,
PdfColor? color,
PdfColor? backgroundColor,
PdfAnnotHighlighting? highlighting,
Set<PdfFieldFlags>? fieldFlags,
this.value,
this.defaultValue,
}) : assert(rect != null),
super(
}) : super(
rect: rect,
fieldType: '/Btn',
fieldName: fieldName,
... ... @@ -695,20 +683,20 @@ class PdfButtonField extends PdfFormField {
fieldFlags: fieldFlags,
);
final bool value;
final bool? value;
final bool defaultValue;
final bool? defaultValue;
@override
void build(PdfPage page, PdfObject object, PdfDict params) {
super.build(page, object, params);
if (value != null) {
params['/V'] = value ? const PdfName('/Yes') : const PdfName('/Off');
params['/V'] = value! ? const PdfName('/Yes') : const PdfName('/Off');
}
if (defaultValue != null) {
params['/DV'] =
defaultValue ? const PdfName('/Yes') : const PdfName('/Off');
defaultValue! ? const PdfName('/Yes') : const PdfName('/Off');
}
}
}
... ...
... ... @@ -335,7 +335,7 @@ class PdfArabic {
final currentLetter = word.codeUnitAt(j);
if (_isArabicDiacritic(currentLetter)) {
newWord.insert(0, _arabicDiacritics[currentLetter]);
newWord.insert(0, _arabicDiacritics[currentLetter]!);
continue;
}
final nextLetter = word
... ...
... ... @@ -25,8 +25,7 @@ class PdfArrayObject extends PdfObject {
PdfArrayObject(
PdfDocument pdfDocument,
this.array,
) : assert(array != null),
super(pdfDocument);
) : super(pdfDocument);
/// The array
final PdfArray array;
... ...
... ... @@ -47,9 +47,7 @@ class PdfBorder extends PdfObject {
this.width, {
this.style = PdfBorderStyle.solid,
this.dash,
}) : assert(width != null),
assert(style != null),
super(pdfDocument);
}) : super(pdfDocument);
/// The style of the border
final PdfBorderStyle style;
... ... @@ -58,7 +56,7 @@ class PdfBorder extends PdfObject {
final double width;
/// This array allows the definition of a dotted line for the border
final List<double> dash;
final List<double>? dash;
@override
void prepare() {
... ... @@ -69,7 +67,7 @@ class PdfBorder extends PdfObject {
params['/W'] = PdfNum(width);
if (dash != null) {
params['/D'] = PdfArray.fromNum(dash);
params['/D'] = PdfArray.fromNum(dash!);
}
}
}
... ...
... ... @@ -30,16 +30,13 @@ class PdfCatalog extends PdfObject {
this.pdfPageList,
this.pageMode,
this.names,
) : assert(pdfPageList != null),
assert(pageMode != null),
assert(names != null),
super(pdfDocument, type: '/Catalog');
) : super(pdfDocument, type: '/Catalog');
/// The pages of the document
final PdfPageList pdfPageList;
/// The outlines of the document
PdfOutline outlines;
PdfOutline? outlines;
/// The initial page mode
final PdfPageMode pageMode;
... ... @@ -65,8 +62,8 @@ class PdfCatalog extends PdfObject {
params['/Pages'] = pdfPageList.ref();
// the Outlines object
if (outlines != null && outlines.outlines.isNotEmpty) {
params['/Outlines'] = outlines.ref();
if (outlines != null && outlines!.outlines.isNotEmpty) {
params['/Outlines'] = outlines!.ref();
}
// the Names object
... ... @@ -77,13 +74,13 @@ class PdfCatalog extends PdfObject {
if (pdfDocument.sign != null) {
params['/Perms'] = PdfDict(<String, PdfDataType>{
'/DocMDP': pdfDocument.sign.ref(),
'/DocMDP': pdfDocument.sign!.ref(),
});
}
final widgets = <PdfAnnot>[];
for (var page in pdfDocument.pdfPageList.pages) {
for (var annot in page.annotations) {
for (var annot in page!.annotations) {
if (annot.annot.subtype == '/Widget') {
widgets.add(annot);
}
... ...
... ... @@ -177,7 +177,7 @@ class PdfColor {
if (component <= 0.03928) {
return component / 12.92;
}
return math.pow((component + 0.055) / 1.055, 2.4);
return math.pow((component + 0.055) / 1.055, 2.4).toDouble();
}
/// Get the luminance
... ... @@ -333,7 +333,7 @@ class PdfColorCmyk extends PdfColor {
double _getHue(
double red, double green, double blue, double max, double delta) {
double hue;
var hue = double.nan;
if (max == 0.0) {
hue = 0.0;
} else if (max == red) {
... ... @@ -546,7 +546,7 @@ class PdfColorHsl extends PdfColor {
final hue = _getHue(red, green, blue, max, delta);
final lightness = (max + min) / 2.0;
// Saturation can exceed 1.0 with rounding errors, so clamp it.
final double saturation = lightness == 1.0
final saturation = lightness == 1.0
? 0.0
: (delta / (1.0 - (2.0 * lightness - 1.0).abs())).clamp(0.0, 1.0);
return PdfColorHsl._(hue, saturation, lightness, alpha, red, green, blue);
... ...
... ... @@ -71,8 +71,7 @@ class PdfBool extends PdfDataType {
class PdfNum extends PdfDataType {
const PdfNum(this.value)
: assert(value != null),
assert(value != double.infinity),
: assert(value != double.infinity),
assert(value != double.nan),
assert(value != double.negativeInfinity);
... ... @@ -114,9 +113,9 @@ class PdfNum extends PdfDataType {
}
class PdfNumList extends PdfDataType {
PdfNumList(this.values) : assert(values != null);
PdfNumList(this.values);
final List<num> values;
final List<num?> values;
@override
void output(PdfStream s) {
... ... @@ -124,7 +123,7 @@ class PdfNumList extends PdfDataType {
if (n > 0) {
s.putByte(0x20);
}
PdfNum(values[n]).output(s);
PdfNum(values[n]!).output(s);
}
}
... ... @@ -159,7 +158,7 @@ class PdfString extends PdfDataType {
return PdfString(_date(date));
}
final Uint8List value;
final Uint8List? value;
final PdfStringFormat format;
... ... @@ -270,11 +269,11 @@ class PdfString extends PdfDataType {
int _codeUnitForDigit(int digit) =>
digit < 10 ? digit + 0x30 : digit + 0x61 - 10;
void _output(PdfStream s, Uint8List value) {
void _output(PdfStream s, Uint8List? value) {
switch (format) {
case PdfStringFormat.binary:
s.putByte(0x3c);
for (int byte in value) {
for (var byte in value!) {
s.putByte(_codeUnitForDigit((byte & 0xF0) >> 4));
s.putByte(_codeUnitForDigit(byte & 0x0F));
}
... ... @@ -282,7 +281,7 @@ class PdfString extends PdfDataType {
break;
case PdfStringFormat.litteral:
s.putByte(40);
_putTextBytes(s, value);
_putTextBytes(s, value!);
s.putByte(41);
break;
}
... ... @@ -351,13 +350,13 @@ class PdfSecString extends PdfString {
return super.output(s);
}
final enc = object.pdfDocument.encryption.encrypt(value, object);
final enc = object.pdfDocument.encryption!.encrypt(value!, object);
_output(s, enc);
}
}
class PdfName extends PdfDataType {
const PdfName(this.value) : assert(value != null);
const PdfName(this.value);
final String value;
... ... @@ -443,24 +442,24 @@ class PdfIndirect extends PdfDataType {
}
class PdfArray extends PdfDataType {
PdfArray([Iterable<PdfDataType> values]) {
PdfArray([Iterable<PdfDataType>? values]) {
if (values != null) {
this.values.addAll(values);
}
}
factory PdfArray.fromObjects(List<PdfObject> objects) {
factory PdfArray.fromObjects(List<PdfObject?> objects) {
return PdfArray(
objects.map<PdfIndirect>((PdfObject e) => e.ref()).toList());
objects.map<PdfIndirect>((PdfObject? e) => e!.ref()).toList());
}
factory PdfArray.fromNum(List<num> list) {
return PdfArray(list.map<PdfNum>((num e) => PdfNum(e)).toList());
factory PdfArray.fromNum(List<num?> list) {
return PdfArray(list.map<PdfNum>((num? e) => PdfNum(e!)).toList());
}
final List<PdfDataType> values = <PdfDataType>[];
final List<PdfDataType?> values = <PdfDataType?>[];
void add(PdfDataType v) {
void add(PdfDataType? v) {
values.add(v);
}
... ... @@ -469,7 +468,7 @@ class PdfArray extends PdfDataType {
s.putString('[');
if (values.isNotEmpty) {
for (var n = 0; n < values.length; n++) {
final val = values[n];
final val = values[n]!;
if (n > 0 &&
!(val is PdfName ||
val is PdfString ||
... ... @@ -490,7 +489,7 @@ class PdfArray extends PdfDataType {
}
// ignore: prefer_collection_literals
final uniques = LinkedHashMap<PdfDataType, bool>();
final uniques = LinkedHashMap<PdfDataType?, bool>();
for (final s in values) {
uniques[s] = true;
}
... ... @@ -512,7 +511,7 @@ class PdfArray extends PdfDataType {
}
class PdfDict extends PdfDataType {
PdfDict([Map<String, PdfDataType> values]) {
PdfDict([Map<String?, PdfDataType>? values]) {
if (values != null) {
this.values.addAll(values);
}
... ... @@ -527,27 +526,27 @@ class PdfDict extends PdfDataType {
);
}
final Map<String, PdfDataType> values = <String, PdfDataType>{};
final Map<String?, PdfDataType?> values = <String?, PdfDataType?>{};
bool get isNotEmpty => values.isNotEmpty;
operator []=(String k, PdfDataType v) {
operator []=(String k, PdfDataType? v) {
values[k] = v;
}
PdfDataType operator [](String k) {
PdfDataType? operator [](String? k) {
return values[k];
}
@override
void output(PdfStream s) {
s.putBytes(const <int>[0x3c, 0x3c]);
values.forEach((String k, PdfDataType v) {
values.forEach((String? k, PdfDataType? v) {
s.putString(k);
if (v is PdfNum || v is PdfBool || v is PdfNull || v is PdfIndirect) {
s.putByte(0x20);
}
v.output(s);
v!.output(s);
});
s.putBytes(const <int>[0x3e, 0x3e]);
}
... ... @@ -598,7 +597,8 @@ class PdfColorType extends PdfDataType {
@override
void output(PdfStream s) {
if (color is PdfColorCmyk) {
final PdfColorCmyk k = color;
// ignore: avoid_as
final k = color as PdfColorCmyk;
PdfArray.fromNum(<double>[
k.cyan,
k.magenta,
... ...
... ... @@ -25,9 +25,7 @@ import 'encryption.dart';
import 'font.dart';
import 'graphic_state.dart';
import 'info.dart';
import 'io/interface.dart'
if (dart.library.io) 'io/vm.dart'
if (dart.library.js) 'io/js.dart';
import 'io/vm.dart' if (dart.library.js) 'io/js.dart';
import 'names.dart';
import 'object.dart';
import 'outline.dart';
... ... @@ -69,12 +67,11 @@ class PdfDocument {
/// This creates a Pdf document
PdfDocument({
PdfPageMode pageMode = PdfPageMode.none,
DeflateCallback deflate,
DeflateCallback? deflate,
bool compress = true,
}) : deflate = compress ? (deflate ?? defaultDeflate) : null,
prev = null {
_objser = 1;
prev = null,
_objser = 1 {
// Now create some standard objects
pdfPageList = PdfPageList(this);
pdfNames = PdfNames(this);
... ... @@ -84,21 +81,20 @@ class PdfDocument {
PdfDocument.load(
this.prev, {
PdfPageMode pageMode = PdfPageMode.none,
DeflateCallback deflate,
DeflateCallback? deflate,
bool compress = true,
}) : deflate = compress ? (deflate ?? defaultDeflate) : null {
_objser = prev.size;
}) : deflate = compress ? (deflate ?? defaultDeflate) : null,
_objser = prev!.size {
// Now create some standard objects
pdfPageList = PdfPageList(this);
pdfNames = PdfNames(this);
catalog = PdfCatalog(this, pdfPageList, pageMode, pdfNames);
// Import the existing document
prev.mergeDocument(this);
prev!.mergeDocument(this);
}
final PdfDocumentParserBase prev;
final PdfDocumentParserBase? prev;
/// This is used to allocate objects a unique serial number in the document.
int _objser;
... ... @@ -109,38 +105,38 @@ class PdfDocument {
final Set<PdfObject> objects = <PdfObject>{};
/// This is the Catalog object, which is required by each Pdf Document
PdfCatalog catalog;
late PdfCatalog catalog;
/// This is the info object. Although this is an optional object, we
/// include it.
PdfInfo info;
PdfInfo? info;
/// This is the Pages object, which is required by each Pdf Document
PdfPageList pdfPageList;
late PdfPageList pdfPageList;
/// The name dictionary
PdfNames pdfNames;
late PdfNames pdfNames;
/// This is the Outline object, which is optional
PdfOutline _outline;
PdfOutline? _outline;
/// This holds a [PdfObject] describing the default border for annotations.
/// It's only used when the document is being written.
PdfObject defaultOutlineBorder;
PdfObject? defaultOutlineBorder;
/// Callback to compress the stream in the pdf file.
/// Use `deflate: zlib.encode` if using dart:io
/// No compression by default
final DeflateCallback deflate;
final DeflateCallback? deflate;
/// Object used to encrypt the document
PdfEncryption encryption;
PdfEncryption? encryption;
/// Object used to sign the document
PdfSignature sign;
PdfSignature? sign;
/// Graphics state, representing only opacity.
PdfGraphicStates _graphicStates;
PdfGraphicStates? _graphicStates;
/// The PDF specification version
final String version = '1.7';
... ... @@ -148,10 +144,10 @@ class PdfDocument {
/// This holds the current fonts
final Set<PdfFont> fonts = <PdfFont>{};
Uint8List _documentID;
Uint8List? _documentID;
/// Generates the document ID
Uint8List get documentID {
Uint8List? get documentID {
if (_documentID == null) {
final rnd = math.Random();
_documentID = Uint8List.fromList(sha256
... ... @@ -168,12 +164,12 @@ class PdfDocument {
/// This returns a specific page. It's used mainly when using a
/// Serialized template file.
PdfPage page(int page) {
PdfPage? page(int page) {
return pdfPageList.pages[page];
}
/// The root outline
PdfOutline get outline {
PdfOutline? get outline {
if (_outline == null) {
_outline = PdfOutline(this);
catalog.outlines = _outline;
... ... @@ -182,7 +178,7 @@ class PdfDocument {
}
/// Graphic states for opacity and transfer modes
PdfGraphicStates get graphicStates {
PdfGraphicStates? get graphicStates {
_graphicStates ??= PdfGraphicStates(this);
return _graphicStates;
}
... ... @@ -206,7 +202,7 @@ class PdfDocument {
Future<Uint8List> save() async {
final os = PdfStream();
if (prev != null) {
os.putBytes(prev.bytes);
os.putBytes(prev!.bytes);
}
await _write(os);
return os.output();
... ...
... ... @@ -23,13 +23,11 @@ import 'image.dart';
class PdfJpegInfo {
/// Load a Jpeg image's metadata
factory PdfJpegInfo(Uint8List image) {
assert(image != null);
final buffer = image.buffer.asByteData();
int width;
int height;
int color;
int? width;
int? height;
int? color;
var offset = image.offsetInBytes;
while (offset < buffer.lengthInBytes) {
while (buffer.getUint8(offset) == 0xff) {
... ... @@ -79,66 +77,69 @@ class PdfJpegInfo {
PdfJpegInfo._(this.width, this.height, this._color, this.tags);
/// Width of the image
final int width;
final int? width;
/// Height of the image
final int height;
final int _color;
final int? _color;
/// Is the image color or greyscale
bool get isRGB => _color == 3;
/// Exif tags discovered
final Map<PdfExifTag, dynamic> tags;
final Map<PdfExifTag, dynamic>? tags;
/// EXIF version
String get exifVersion => tags == null || tags[PdfExifTag.ExifVersion] == null
? null
: utf8.decode(tags[PdfExifTag.ExifVersion]);
String? get exifVersion =>
tags == null || tags![PdfExifTag.ExifVersion] == null
? null
: utf8.decode(tags![PdfExifTag.ExifVersion]);
/// Flashpix format version
String get flashpixVersion =>
tags == null || tags[PdfExifTag.FlashpixVersion] == null
String? get flashpixVersion =>
tags == null || tags![PdfExifTag.FlashpixVersion] == null
? null
: utf8.decode(tags[PdfExifTag.FlashpixVersion]);
: utf8.decode(tags![PdfExifTag.FlashpixVersion]);
/// Rotation angle of this image
PdfImageOrientation get orientation {
if (tags == null || tags[PdfExifTag.Orientation] == null) {
if (tags == null || tags![PdfExifTag.Orientation] == null) {
return PdfImageOrientation.topLeft;
}
try {
return PdfImageOrientation.values[tags[PdfExifTag.Orientation] - 1];
return PdfImageOrientation.values[tags![PdfExifTag.Orientation] - 1];
} on RangeError {
return PdfImageOrientation.topLeft;
}
}
/// Exif horizontal resolution
double get xResolution => tags == null || tags[PdfExifTag.XResolution] == null
? null
: tags[PdfExifTag.XResolution][0].toDouble() /
tags[PdfExifTag.XResolution][1].toDouble();
double? get xResolution =>
tags == null || tags![PdfExifTag.XResolution] == null
? null
: tags![PdfExifTag.XResolution][0].toDouble() /
tags![PdfExifTag.XResolution][1].toDouble();
/// Exif vertical resolution
double get yResolution => tags == null || tags[PdfExifTag.YResolution] == null
? null
: tags[PdfExifTag.YResolution][0].toDouble() /
tags[PdfExifTag.YResolution][1].toDouble();
double? get yResolution =>
tags == null || tags![PdfExifTag.YResolution] == null
? null
: tags![PdfExifTag.YResolution][0].toDouble() /
tags![PdfExifTag.YResolution][1].toDouble();
/// Exif horizontal pixel dimension
int get pixelXDimension =>
tags == null || tags[PdfExifTag.PixelXDimension] == null
int? get pixelXDimension =>
tags == null || tags![PdfExifTag.PixelXDimension] == null
? width
: tags[PdfExifTag.PixelXDimension];
: tags![PdfExifTag.PixelXDimension];
/// Exif vertical pixel dimension
int get pixelYDimension =>
tags == null || tags[PdfExifTag.PixelYDimension] == null
int? get pixelYDimension =>
tags == null || tags![PdfExifTag.PixelYDimension] == null
? height
: tags[PdfExifTag.PixelYDimension];
: tags![PdfExifTag.PixelYDimension];
@override
String toString() => '''width: $width height: $height
... ... @@ -147,7 +148,7 @@ xResolution: $xResolution yResolution: $yResolution
pixelXDimension: $pixelXDimension pixelYDimension: $pixelYDimension
orientation: $orientation''';
static Map<PdfExifTag, dynamic> _findExifInJpeg(ByteData buffer) {
static Map<PdfExifTag, dynamic>? _findExifInJpeg(ByteData buffer) {
if ((buffer.getUint8(0) != 0xFF) || (buffer.getUint8(1) != 0xD8)) {
return <PdfExifTag, dynamic>{}; // Not a valid JPEG
}
... ... @@ -317,7 +318,7 @@ orientation: $orientation''';
allowMalformed: true);
}
static Map<PdfExifTag, dynamic> _readEXIFData(ByteData buffer, int start) {
static Map<PdfExifTag, dynamic>? _readEXIFData(ByteData buffer, int start) {
final startingString = _getStringFromDB(buffer, start, 4);
if (startingString != 'Exif') {
// Not valid EXIF data! $startingString
... ... @@ -353,8 +354,12 @@ orientation: $orientation''';
_readTags(buffer, tiffOffset, tiffOffset + firstIFDOffset, bigEnd);
if (tags.containsKey(PdfExifTag.ExifIFDPointer)) {
final exifData = _readTags(buffer, tiffOffset,
tiffOffset + tags[PdfExifTag.ExifIFDPointer], bigEnd);
final exifData = _readTags(
buffer,
tiffOffset,
// ignore: avoid_as
tiffOffset + tags[PdfExifTag.ExifIFDPointer] as int,
bigEnd);
tags.addAll(exifData);
}
... ...
... ... @@ -16,8 +16,6 @@
import 'dart:convert';
import 'package:meta/meta.dart';
import 'data_types.dart';
import 'document.dart';
import 'font_metrics.dart';
... ... @@ -31,9 +29,8 @@ import 'type1_fonts.dart';
abstract class PdfFont extends PdfObject {
/// Constructs a [PdfFont]. This will attempt to map the font from a known
/// font name to that in Pdf, defaulting to Helvetica if not possible.
PdfFont.create(PdfDocument pdfDocument, {@required this.subtype})
: assert(subtype != null),
super(pdfDocument, type: '/Font') {
PdfFont.create(PdfDocument pdfDocument, {required this.subtype})
: super(pdfDocument, type: '/Font') {
pdfDocument.fonts.add(this);
}
... ... @@ -137,14 +134,14 @@ See https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management
String get name => '/F$objser';
/// The font's real name
String get fontName => null;
String get fontName;
/// Spans the distance between the baseline and the top of the glyph that
/// reaches farthest from the baseline
double get ascent => null;
double get ascent;
/// Spans the distance between the baseline and the lowest descending glyph
double get descent => null;
double get descent;
/// Default width of a glyph
static const double defaultGlyphWidth = 0.600;
... ...
... ... @@ -25,9 +25,7 @@ class PdfFontDescriptor extends PdfObject {
PdfFontDescriptor(
this.ttfFont,
this.file,
) : assert(ttfFont != null),
assert(file != null),
super(ttfFont.pdfDocument, type: '/FontDescriptor');
) : super(ttfFont.pdfDocument, type: '/FontDescriptor');
/// File data
final PdfObjectStream file;
... ...
... ... @@ -25,22 +25,18 @@ import 'rect.dart';
class PdfFontMetrics {
/// Create a PdfFontMetrics object
const PdfFontMetrics({
@required this.left,
@required this.top,
@required this.right,
@required this.bottom,
double ascent,
double descent,
double advanceWidth,
double leftBearing,
required this.left,
required this.top,
required this.right,
required this.bottom,
double? ascent,
double? descent,
double? advanceWidth,
double? leftBearing,
}) : ascent = ascent ?? bottom,
descent = descent ?? top,
advanceWidth = advanceWidth ?? right - left,
leftBearing = leftBearing ?? left,
assert(left != null),
assert(top != null),
assert(right != null),
assert(bottom != null),
assert(left <= right),
assert(top <= bottom),
assert((descent ?? top) <= (ascent ?? bottom));
... ... @@ -54,15 +50,15 @@ class PdfFontMetrics {
return PdfFontMetrics.zero;
}
double left;
double top;
double? left;
double? top;
var right = 0.0;
double bottom;
double ascent;
double descent;
double lastBearing;
double firstBearing;
double spacing;
double? bottom;
double? ascent;
double? descent;
late double lastBearing;
double? firstBearing;
late double spacing;
for (var metric in metrics) {
firstBearing ??= metric.leftBearing;
... ... @@ -78,10 +74,10 @@ class PdfFontMetrics {
}
return PdfFontMetrics(
left: left,
top: top,
left: left!,
top: top!,
right: right - lastBearing - spacing,
bottom: bottom,
bottom: bottom!,
ascent: ascent,
descent: descent,
advanceWidth: right - spacing,
... ... @@ -143,14 +139,14 @@ class PdfFontMetrics {
/// Make a copy of this object
PdfFontMetrics copyWith({
double left,
double top,
double right,
double bottom,
double ascent,
double descent,
double advanceWidth,
double leftBearing,
double? left,
double? top,
double? right,
double? bottom,
double? ascent,
double? descent,
double? advanceWidth,
double? leftBearing,
}) {
return PdfFontMetrics(
left: left ?? this.left,
... ...
... ... @@ -14,8 +14,6 @@
* limitations under the License.
*/
import 'package:meta/meta.dart';
import 'color.dart';
import 'data_types.dart';
import 'document.dart';
... ... @@ -27,8 +25,8 @@ abstract class PdfBaseFunction extends PdfObject {
factory PdfBaseFunction.colorsAndStops(
PdfDocument pdfDocument,
List<PdfColor> colors, [
List<double> stops,
List<PdfColor?> colors, [
List<double>? stops,
]) {
if (stops == null || stops.isEmpty) {
return PdfFunction.fromColors(pdfDocument, colors);
... ... @@ -81,10 +79,10 @@ class PdfFunction extends PdfObjectStream implements PdfBaseFunction {
}) : super(pdfDocument);
factory PdfFunction.fromColors(
PdfDocument pdfDocument, List<PdfColor> colors) {
PdfDocument pdfDocument, List<PdfColor?> colors) {
final data = <int>[];
for (final color in colors) {
data.add((color.red * 255.0).round() & 0xff);
data.add((color!.red * 255.0).round() & 0xff);
data.add((color.green * 255.0).round() & 0xff);
data.add((color.blue * 255.0).round() & 0xff);
}
... ... @@ -96,7 +94,7 @@ class PdfFunction extends PdfObjectStream implements PdfBaseFunction {
);
}
final List<int> data;
final List<int>? data;
final int bitsPerSample;
... ... @@ -108,7 +106,7 @@ class PdfFunction extends PdfObjectStream implements PdfBaseFunction {
@override
void prepare() {
buf.putBytes(data);
buf.putBytes(data!);
super.prepare();
params['/FunctionType'] = const PdfNum(0);
... ... @@ -116,7 +114,7 @@ class PdfFunction extends PdfObjectStream implements PdfBaseFunction {
params['/Order'] = PdfNum(order);
params['/Domain'] = PdfArray.fromNum(domain);
params['/Range'] = PdfArray.fromNum(range);
params['/Size'] = PdfArray.fromNum(<int>[data.length ~/ order]);
params['/Size'] = PdfArray.fromNum(<int>[data!.length ~/ order]);
}
@override
... ... @@ -126,13 +124,11 @@ class PdfFunction extends PdfObjectStream implements PdfBaseFunction {
class PdfStitchingFunction extends PdfBaseFunction {
PdfStitchingFunction(
PdfDocument pdfDocument, {
@required this.functions,
@required this.bounds,
required this.functions,
required this.bounds,
this.domainStart = 0,
this.domainEnd = 1,
}) : assert(functions != null),
assert(bounds != null),
super(pdfDocument);
}) : super(pdfDocument);
final List<PdfFunction> functions;
... ...
... ... @@ -86,19 +86,19 @@ class PdfGraphicState {
const PdfGraphicState({this.opacity, this.blendMode, this.softMask});
/// The opacity to apply to this graphic state
final double opacity;
final double? opacity;
/// The current blend mode to be used
final PdfBlendMode blendMode;
final PdfBlendMode? blendMode;
final PdfSoftMask softMask;
final PdfSoftMask? softMask;
PdfDict output() {
final params = PdfDict();
if (opacity != null) {
params['/CA'] = PdfNum(opacity);
params['/ca'] = PdfNum(opacity);
params['/CA'] = PdfNum(opacity!);
params['/ca'] = PdfNum(opacity!);
}
if (blendMode != null) {
... ... @@ -108,7 +108,7 @@ class PdfGraphicState {
}
if (softMask != null) {
params['/SMask'] = softMask.output();
params['/SMask'] = softMask!.output();
}
return params;
... ...
... ... @@ -78,7 +78,7 @@ mixin PdfGraphicStream on PdfObject {
}
/// Get the default font of this graphic object
PdfFont getDefaultFont() {
PdfFont? getDefaultFont() {
if (pdfDocument.fonts.isEmpty) {
PdfFont.helvetica(pdfDocument);
}
... ... @@ -88,7 +88,7 @@ mixin PdfGraphicStream on PdfObject {
/// Generate a name for the graphic state object
String stateName(PdfGraphicState state) {
return pdfDocument.graphicStates.stateName(state);
return pdfDocument.graphicStates!.stateName(state);
}
@override
... ... @@ -135,7 +135,7 @@ mixin PdfGraphicStream on PdfObject {
'/K': PdfBool(knockoutTransparency),
});
resources['/ExtGState'] = pdfDocument.graphicStates.ref();
resources['/ExtGState'] = pdfDocument.graphicStates!.ref();
}
if (params.containsKey('/Resources')) {
... ... @@ -155,6 +155,6 @@ class PdfGraphicXObject extends PdfXObject with PdfGraphicStream {
/// Creates a Graphic XObject
PdfGraphicXObject(
PdfDocument pdfDocument, [
String subtype,
String? subtype,
]) : super(pdfDocument, subtype);
}
... ...
... ... @@ -88,8 +88,8 @@ enum PdfTextRenderingMode {
@immutable
class _PdfGraphicsContext {
const _PdfGraphicsContext({
@required this.ctm,
}) : assert(ctm != null);
required this.ctm,
});
final Matrix4 ctm;
_PdfGraphicsContext copy() => _PdfGraphicsContext(
... ... @@ -108,16 +108,16 @@ class PdfGraphics {
static const double _m4 = 0.551784;
/// Graphic context
_PdfGraphicsContext _context;
late _PdfGraphicsContext _context;
final Queue<_PdfGraphicsContext> _contextQueue = Queue<_PdfGraphicsContext>();
final PdfGraphicStream _page;
final PdfGraphicStream? _page;
/// Buffer where to write the graphic operations
final PdfStream buf;
/// Default font if none selected
PdfFont get defaultFont => _page.getDefaultFont();
PdfFont? get defaultFont => _page!.getDefaultFont();
/// Draw a surface on the previously defined shape
/// set evenOdd to false to use the nonzero winding number rule to determine the region to fill and to true to use the even-odd rule to determine the region to fill
... ... @@ -150,7 +150,7 @@ class PdfGraphics {
/// Apply a shader
void applyShader(PdfShading shader) {
// The shader needs to be registered in the page resources
_page.addShader(shader);
_page!.addShader(shader);
buf.putString('${shader.name} sh\n');
}
... ... @@ -174,12 +174,12 @@ class PdfGraphics {
}
/// Draws an image onto the page.
void drawImage(PdfImage img, double x, double y, [double w, double h]) {
void drawImage(PdfImage img, double x, double y, [double? w, double? h]) {
w ??= img.width.toDouble();
h ??= img.height.toDouble() * w / img.width.toDouble();
// The image needs to be registered in the page resources
_page.addXObject(img);
_page!.addXObject(img);
// q w 0 0 h x y cm % the coordinate matrix
buf.putString('q ');
... ... @@ -214,7 +214,7 @@ class PdfGraphics {
}
/// Draws a line between two coordinates.
void drawLine(double x1, double y1, double x2, double y2) {
void drawLine(double? x1, double? y1, double? x2, double? y2) {
moveTo(x1, y1);
lineTo(x2, y2);
}
... ... @@ -230,12 +230,12 @@ class PdfGraphics {
/// Draws a Rectangle
void drawRect(
double x,
double y,
double w,
double h,
double? x,
double? y,
double? w,
double? h,
) {
PdfNumList(<double>[x, y, w, h]).output(buf);
PdfNumList(<double?>[x, y, w, h]).output(buf);
buf.putString(' re\n');
}
... ... @@ -262,17 +262,17 @@ class PdfGraphics {
void setFont(
PdfFont font,
double size, {
double charSpace = 0,
double? charSpace = 0,
double wordSpace = 0,
double scale = 1,
PdfTextRenderingMode mode = PdfTextRenderingMode.fill,
PdfTextRenderingMode? mode = PdfTextRenderingMode.fill,
double rise = 0,
}) {
buf.putString('${font.name} ');
PdfNum(size).output(buf);
buf.putString(' Tf\n');
if (charSpace != 0) {
PdfNum(charSpace).output(buf);
PdfNum(charSpace!).output(buf);
buf.putString(' Tc\n');
}
if (wordSpace != 0) {
... ... @@ -288,7 +288,7 @@ class PdfGraphics {
buf.putString(' Ts\n');
}
if (mode != PdfTextRenderingMode.fill) {
buf.putString('${mode.index} Tr\n');
buf.putString('${mode!.index} Tr\n');
}
}
... ... @@ -297,18 +297,18 @@ class PdfGraphics {
PdfFont font,
double size,
String s,
double x,
double? x,
double y, {
double charSpace = 0,
double? charSpace = 0,
double wordSpace = 0,
double scale = 1,
PdfTextRenderingMode mode = PdfTextRenderingMode.fill,
PdfTextRenderingMode? mode = PdfTextRenderingMode.fill,
double rise = 0,
}) {
_page.addFont(font);
_page!.addFont(font);
buf.putString('BT ');
PdfNumList(<double>[x, y]).output(buf);
PdfNumList(<double?>[x, y]).output(buf);
buf.putString(' Td ');
setFont(font, size,
charSpace: charSpace,
... ... @@ -326,31 +326,31 @@ class PdfGraphics {
}
/// Sets the color for drawing
void setColor(PdfColor color) {
void setColor(PdfColor? color) {
setFillColor(color);
setStrokeColor(color);
}
/// Sets the fill color for drawing
void setFillColor(PdfColor color) {
void setFillColor(PdfColor? color) {
if (color is PdfColorCmyk) {
PdfNumList(<double>[color.cyan, color.magenta, color.yellow, color.black])
.output(buf);
buf.putString(' k\n');
} else {
PdfNumList(<double>[color.red, color.green, color.blue]).output(buf);
PdfNumList(<double>[color!.red, color.green, color.blue]).output(buf);
buf.putString(' rg\n');
}
}
/// Sets the stroke color for drawing
void setStrokeColor(PdfColor color) {
void setStrokeColor(PdfColor? color) {
if (color is PdfColorCmyk) {
PdfNumList(<double>[color.cyan, color.magenta, color.yellow, color.black])
.output(buf);
buf.putString(' K\n');
} else {
PdfNumList(<double>[color.red, color.green, color.blue]).output(buf);
PdfNumList(<double>[color!.red, color.green, color.blue]).output(buf);
buf.putString(' RG\n');
}
}
... ... @@ -358,20 +358,20 @@ class PdfGraphics {
/// Sets the fill pattern for drawing
void setFillPattern(PdfPattern pattern) {
// The shader needs to be registered in the page resources
_page.addPattern(pattern);
_page!.addPattern(pattern);
buf.putString('/Pattern cs${pattern.name} scn\n');
}
/// Sets the stroke pattern for drawing
void setStrokePattern(PdfPattern pattern) {
// The shader needs to be registered in the page resources
_page.addPattern(pattern);
_page!.addPattern(pattern);
buf.putString('/Pattern CS${pattern.name} SCN\n');
}
/// Set the graphic state for drawing
void setGraphicState(PdfGraphicState state) {
final name = _page.stateName(state);
final name = _page!.stateName(state);
buf.putString('$name gs\n');
}
... ... @@ -389,14 +389,14 @@ class PdfGraphics {
}
/// This adds a line segment to the current path
void lineTo(double x, double y) {
PdfNumList(<double>[x, y]).output(buf);
void lineTo(double? x, double? y) {
PdfNumList(<double?>[x, y]).output(buf);
buf.putString(' l\n');
}
/// This moves the current drawing point.
void moveTo(double x, double y) {
PdfNumList(<double>[x, y]).output(buf);
void moveTo(double? x, double? y) {
PdfNumList(<double?>[x, y]).output(buf);
buf.putString(' m\n');
}
... ... @@ -404,8 +404,8 @@ class PdfGraphics {
/// using (x1,y1) as the control point at the beginning of the curve
/// and (x2,y2) as the control point at the end of the curve.
void curveTo(
double x1, double y1, double x2, double y2, double x3, double y3) {
PdfNumList(<double>[x1, y1, x2, y2, x3, y3]).output(buf);
double? x1, double? y1, double? x2, double? y2, double? x3, double? y3) {
PdfNumList(<double?>[x1, y1, x2, y2, x3, y3]).output(buf);
buf.putString(' c\n');
}
... ... @@ -524,7 +524,7 @@ class PdfGraphics {
/// the constraints imposed by the other parameters. large and sweep flags
/// contribute to the automatic calculations and help determine how the arc is drawn.
void bezierArc(
double x1, double y1, double rx, double ry, double x2, double y2,
double? x1, double? y1, double rx, double ry, double? x2, double? y2,
{bool large = false, bool sweep = false, double phi = 0.0}) {
if (x1 == x2 && y1 == y2) {
// From https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes:
... ... @@ -542,12 +542,12 @@ class PdfGraphics {
// Our box bézier arcs can't handle rotations directly
// move to a well known point, eliminate phi and transform the other point
final mat = Matrix4.identity();
mat.translate(-x1, -y1);
mat.translate(-x1!, -y1!);
mat.rotateZ(-phi);
final tr = mat.transform3(Vector3(x2, y2, 0));
final tr = mat.transform3(Vector3(x2!, y2!, 0));
_endToCenterParameters(0, 0, tr[0], tr[1], large, sweep, rx, ry);
} else {
_endToCenterParameters(x1, y1, x2, y2, large, sweep, rx, ry);
_endToCenterParameters(x1!, y1!, x2!, y2!, large, sweep, rx, ry);
}
}
... ...
... ... @@ -17,7 +17,6 @@
import 'dart:typed_data';
import 'package:image/image.dart' as im;
import 'package:meta/meta.dart';
import 'data_types.dart';
import 'document.dart';
... ... @@ -57,14 +56,12 @@ class PdfImage extends PdfXObject {
/// Creates a new [PdfImage] instance.
factory PdfImage(
PdfDocument pdfDocument, {
@required Uint8List image,
@required int width,
@required int height,
required Uint8List image,
required int width,
required int height,
bool alpha = true,
PdfImageOrientation orientation = PdfImageOrientation.topLeft,
}) {
assert(image != null);
final im = PdfImage._(
pdfDocument,
width,
... ... @@ -104,15 +101,13 @@ class PdfImage extends PdfXObject {
/// Create an image from a jpeg file
factory PdfImage.jpeg(
PdfDocument pdfDocument, {
@required Uint8List image,
PdfImageOrientation orientation,
required Uint8List image,
PdfImageOrientation? orientation,
}) {
assert(image != null);
final info = PdfJpegInfo(image);
final im = PdfImage._(
pdfDocument,
info.width,
info.width!,
info.height,
orientation ?? info.orientation,
);
... ... @@ -135,11 +130,9 @@ class PdfImage extends PdfXObject {
/// Create an image from an [im.Image] object
factory PdfImage.fromImage(
PdfDocument pdfDocument, {
@required im.Image image,
required im.Image image,
PdfImageOrientation orientation = PdfImageOrientation.topLeft,
}) {
assert(image != null);
return PdfImage(
pdfDocument,
image: image.getBytes(format: im.Format.rgba),
... ... @@ -153,16 +146,17 @@ class PdfImage extends PdfXObject {
/// Create an image from an image file
factory PdfImage.file(
PdfDocument pdfDocument, {
@required Uint8List bytes,
required Uint8List bytes,
PdfImageOrientation orientation = PdfImageOrientation.topLeft,
}) {
assert(bytes != null);
if (im.JpegDecoder().isValidFile(bytes)) {
return PdfImage.jpeg(pdfDocument, image: bytes);
}
final image = im.decodeImage(bytes);
if (image == null) {
throw 'Unable to decode image';
}
return PdfImage.fromImage(
pdfDocument,
image: image,
... ...
... ... @@ -30,19 +30,19 @@ class PdfInfo extends PdfObject {
this.producer})
: super(pdfDocument) {
if (author != null) {
params['/Author'] = PdfSecString.fromString(this, author);
params['/Author'] = PdfSecString.fromString(this, author!);
}
if (creator != null) {
params['/Creator'] = PdfSecString.fromString(this, creator);
params['/Creator'] = PdfSecString.fromString(this, creator!);
}
if (title != null) {
params['/Title'] = PdfSecString.fromString(this, title);
params['/Title'] = PdfSecString.fromString(this, title!);
}
if (subject != null) {
params['/Subject'] = PdfSecString.fromString(this, subject);
params['/Subject'] = PdfSecString.fromString(this, subject!);
}
if (keywords != null) {
params['/Keywords'] = PdfSecString.fromString(this, keywords);
params['/Keywords'] = PdfSecString.fromString(this, keywords!);
}
if (producer != null) {
params['/Producer'] =
... ... @@ -57,20 +57,20 @@ class PdfInfo extends PdfObject {
static const String _libraryName = 'https://github.com/DavBfr/dart_pdf';
/// Author of this document
final String author;
final String? author;
/// Creator of this document
final String creator;
final String? creator;
/// Title of this document
final String title;
final String? title;
/// Subject of this document
final String subject;
final String? subject;
/// Keywords of this document
final String keywords;
final String? keywords;
/// Application that created this document
final String producer;
final String? producer;
}
... ...
/*
* 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.
*/
import 'package:pdf/pdf.dart';
/// Zip compression function
DeflateCallback defaultDeflate;
... ... @@ -30,12 +30,11 @@ class PdfNames extends PdfObject {
void addDest(
String name,
PdfPage page, {
double posX,
double posY,
double posZ,
double? posX,
double? posY,
double? posZ,
}) {
assert(page.pdfDocument == pdfDocument);
assert(name != null);
_dests[name] = PdfDict(<String, PdfDataType>{
'/D': PdfArray(<PdfDataType>[
... ...
... ... @@ -26,11 +26,10 @@ class PdfObject {
/// Pdf Object Type
PdfObject(
this.pdfDocument, {
String type,
String? type,
this.objgen = 0,
int objser,
}) : assert(pdfDocument != null),
objser = objser ?? pdfDocument.genSerial() {
int? objser,
}) : objser = objser ?? pdfDocument.genSerial() {
if (type != null) {
params['/Type'] = PdfName(type);
}
... ...
... ... @@ -27,7 +27,7 @@ class PdfObjectStream extends PdfObject {
/// Constructs a stream object to store some data
PdfObjectStream(
PdfDocument pdfDocument, {
String type,
String? type,
this.isBinary = false,
}) : super(pdfDocument, type: type);
... ... @@ -37,7 +37,7 @@ class PdfObjectStream extends PdfObject {
/// defines if the stream needs to be converted to ascii85
final bool isBinary;
Uint8List _data;
Uint8List? _data;
@override
void prepare() {
... ... @@ -48,7 +48,7 @@ class PdfObjectStream extends PdfObject {
_data = buf.output();
} else if (pdfDocument.deflate != null) {
final original = buf.output();
final Uint8List newData = pdfDocument.deflate(original);
final newData = Uint8List.fromList(pdfDocument.deflate!(original));
if (newData.lengthInBytes < original.lengthInBytes) {
params['/Filter'] = const PdfName('/FlateDecode');
_data = newData;
... ... @@ -67,9 +67,9 @@ class PdfObjectStream extends PdfObject {
}
}
if (pdfDocument.encryption != null) {
_data = pdfDocument.encryption.encrypt(_data, this);
_data = pdfDocument.encryption!.encrypt(_data!, this);
}
params['/Length'] = PdfNum(_data.length);
params['/Length'] = PdfNum(_data!.length);
}
@override
... ... @@ -77,7 +77,7 @@ class PdfObjectStream extends PdfObject {
super.writeContent(os);
os.putString('stream\n');
os.putBytes(_data);
os.putBytes(_data!);
os.putString('\nendstream\n');
}
}
... ...
... ... @@ -59,30 +59,28 @@ class PdfOutline extends PdfObject {
this.destMode = PdfOutlineMode.fitPage,
this.style = PdfOutlineStyle.normal,
}) : assert(anchor == null || (dest == null && rect == null)),
assert(destMode != null),
assert(style != null),
super(pdfDocument);
/// This holds any outlines below us
List<PdfOutline> outlines = <PdfOutline>[];
/// For subentries, this points to it's parent outline
PdfOutline parent;
PdfOutline? parent;
/// This is this outlines Title
final String title;
final String? title;
/// The destination page
PdfPage dest;
PdfPage? dest;
/// The region on the destination page
final PdfRect rect;
final PdfRect? rect;
/// Named destination
final String anchor;
final String? anchor;
/// Color of the outline text
final PdfColor color;
final PdfColor? color;
/// How the destination is handled
final PdfOutlineMode destMode;
... ... @@ -91,7 +89,7 @@ class PdfOutline extends PdfObject {
final PdfOutlineStyle style;
/// External level for this outline
int effectiveLevel;
int? effectiveLevel;
/// This method creates an outline, and attaches it to this one.
/// When the outline is selected, the supplied region is displayed.
... ... @@ -106,10 +104,10 @@ class PdfOutline extends PdfObject {
// These are for kids only
if (parent != null) {
params['/Title'] = PdfSecString.fromString(this, title);
params['/Title'] = PdfSecString.fromString(this, title!);
if (color != null) {
params['/C'] = PdfColorType(color);
params['/C'] = PdfColorType(color!);
}
if (style != PdfOutlineStyle.normal) {
... ... @@ -117,23 +115,23 @@ class PdfOutline extends PdfObject {
}
if (anchor != null) {
params['/Dest'] = PdfSecString.fromString(this, anchor);
params['/Dest'] = PdfSecString.fromString(this, anchor!);
} else {
final dests = PdfArray();
dests.add(dest.ref());
dests.add(dest!.ref());
if (destMode == PdfOutlineMode.fitPage) {
dests.add(const PdfName('/Fit'));
} else {
dests.add(const PdfName('/FitR'));
dests.add(PdfNum(rect.left));
dests.add(PdfNum(rect.bottom));
dests.add(PdfNum(rect.right));
dests.add(PdfNum(rect.top));
dests.add(PdfNum(rect!.left));
dests.add(PdfNum(rect!.bottom));
dests.add(PdfNum(rect!.right));
dests.add(PdfNum(rect!.top));
}
params['/Dest'] = dests;
}
params['/Parent'] = parent.ref();
params['/Parent'] = parent!.ref();
// were a descendent, so by default we are closed. Find out how many
// entries are below us
... ... @@ -142,15 +140,15 @@ class PdfOutline extends PdfObject {
params['/Count'] = PdfNum(-c);
}
final index = parent.getIndex(this);
final index = parent!.getIndex(this);
if (index > 0) {
// Now if were not the first, then we have a /Prev node
params['/Prev'] = parent.getNode(index - 1).ref();
params['/Prev'] = parent!.getNode(index - 1).ref();
}
if (index < parent.getLast()) {
if (index < parent!.getLast()) {
// We have a /Next node
params['/Next'] = parent.getNode(index + 1).ref();
params['/Next'] = parent!.getNode(index + 1).ref();
}
} else {
// the number of outlines in this document
... ...
... ... @@ -38,16 +38,16 @@ class PdfOutput {
List<PdfXref> offsets = <PdfXref>[];
/// This is used to track the /Root object (catalog)
PdfObject rootID;
PdfObject? rootID;
/// This is used to track the /Info object (info)
PdfObject infoID;
PdfObject? infoID;
/// This is used to track the /Encrypt object (encryption)
PdfEncryption encryptID;
PdfEncryption? encryptID;
/// This is used to track the /Sign object (signature)
PdfSignature signatureID;
PdfSignature? signatureID;
/// This method writes a [PdfObject] to the stream.
void write(PdfObject ob) {
... ... @@ -84,7 +84,7 @@ class PdfOutput {
for (var x in offsets) {
// check to see if block is in range
if (lastid != null && x.id != (lastid + 1)) {
if (x.id != (lastid + 1)) {
// no, so write this block, and reset
writeblock(firstid, block);
block.clear();
... ... @@ -105,13 +105,13 @@ class PdfOutput {
final params = PdfDict();
// the number of entries (REQUIRED)
params['/Size'] = PdfNum(rootID.pdfDocument.objser);
params['/Size'] = PdfNum(rootID!.pdfDocument.objser);
// the /Root catalog indirect reference (REQUIRED)
if (rootID != null) {
params['/Root'] = rootID.ref();
params['/Root'] = rootID!.ref();
final id =
PdfString(rootID.pdfDocument.documentID, PdfStringFormat.binary);
PdfString(rootID!.pdfDocument.documentID, PdfStringFormat.binary);
params['/ID'] = PdfArray(<PdfDataType>[id, id]);
} else {
throw Exception('Root object is not present in document');
... ... @@ -119,16 +119,16 @@ class PdfOutput {
// the /Info reference (OPTIONAL)
if (infoID != null) {
params['/Info'] = infoID.ref();
params['/Info'] = infoID!.ref();
}
// the /Encrypt reference (OPTIONAL)
if (encryptID != null) {
params['/Encrypt'] = encryptID.ref();
params['/Encrypt'] = encryptID!.ref();
}
if (rootID.pdfDocument.prev != null) {
params['/Prev'] = PdfNum(rootID.pdfDocument.prev.xrefOffset);
if (rootID!.pdfDocument.prev != null) {
params['/Prev'] = PdfNum(rootID!.pdfDocument.prev!.xrefOffset);
}
// end the trailer object
... ... @@ -136,7 +136,7 @@ class PdfOutput {
os.putString('\nstartxref\n$xref\n%%EOF\n');
if (signatureID != null) {
await signatureID.writeSignature(os);
await signatureID!.writeSignature(os);
}
}
... ...
... ... @@ -30,7 +30,7 @@ class PdfPage extends PdfObject with PdfGraphicStream {
PdfPage(
PdfDocument pdfDocument, {
this.pageFormat = PdfPageFormat.standard,
int index,
int? index,
}) : super(pdfDocument, type: '/Page') {
if (index != null) {
pdfDocument.pdfPageList.pages.insert(index, this);
... ... @@ -60,7 +60,7 @@ class PdfPage extends PdfObject with PdfGraphicStream {
}
/// This adds an Annotation to the page.
void addAnnotation(PdfObject ob) {
void addAnnotation(PdfAnnot ob) {
annotations.add(ob);
}
... ...
... ... @@ -24,7 +24,7 @@ class PdfPageFormat {
double marginBottom = 0.0,
double marginLeft = 0.0,
double marginRight = 0.0,
double marginAll})
double? marginAll})
: assert(width > 0),
assert(height > 0),
marginTop = marginAll ?? marginTop,
... ... @@ -67,12 +67,12 @@ class PdfPageFormat {
final double marginRight;
PdfPageFormat copyWith(
{double width,
double height,
double marginTop,
double marginBottom,
double marginLeft,
double marginRight}) {
{double? width,
double? height,
double? marginTop,
double? marginBottom,
double? marginLeft,
double? marginRight}) {
return PdfPageFormat(width ?? this.width, height ?? this.height,
marginTop: marginTop ?? this.marginTop,
marginBottom: marginBottom ?? this.marginBottom,
... ... @@ -99,7 +99,10 @@ class PdfPageFormat {
height >= width ? this : copyWith(width: height, height: width);
PdfPageFormat applyMargin(
{double left, double top, double right, double bottom}) =>
{required double left,
required double top,
required double right,
required double bottom}) =>
copyWith(
marginLeft: math.max(marginLeft, left),
marginTop: math.max(marginTop, top),
... ...
... ... @@ -25,7 +25,7 @@ class PdfPageList extends PdfObject {
PdfPageList(PdfDocument pdfDocument) : super(pdfDocument, type: '/Pages');
/// This holds the pages
final List<PdfPage> pages = <PdfPage>[];
final List<PdfPage?> pages = <PdfPage?>[];
@override
void prepare() {
... ...
... ... @@ -14,7 +14,6 @@
* limitations under the License.
*/
import 'package:meta/meta.dart';
import 'package:vector_math/vector_math_64.dart';
import 'data_types.dart';
... ... @@ -32,7 +31,7 @@ abstract class PdfPattern extends PdfObject {
final int patternType;
final Matrix4 matrix;
final Matrix4? matrix;
@override
void prepare() {
... ... @@ -41,7 +40,7 @@ abstract class PdfPattern extends PdfObject {
params['/PatternType'] = PdfNum(patternType);
if (matrix != null) {
final s = matrix.storage;
final s = matrix!.storage;
params['/Matrix'] =
PdfArray.fromNum(<double>[s[0], s[1], s[4], s[5], s[12], s[13]]);
}
... ... @@ -51,15 +50,14 @@ abstract class PdfPattern extends PdfObject {
class PdfShadingPattern extends PdfPattern {
PdfShadingPattern(
PdfDocument pdfDocument, {
@required this.shading,
Matrix4 matrix,
required this.shading,
Matrix4? matrix,
this.graphicState,
}) : assert(shading != null),
super(pdfDocument, 2, matrix);
}) : super(pdfDocument, 2, matrix);
final PdfShading shading;
final PdfGraphicState graphicState;
final PdfGraphicState? graphicState;
@override
void prepare() {
... ... @@ -68,7 +66,7 @@ class PdfShadingPattern extends PdfPattern {
params['/Shading'] = shading.ref();
if (graphicState != null) {
params['/ExtGState'] = graphicState.output();
params['/ExtGState'] = graphicState!.output();
}
}
}
... ...
... ... @@ -14,8 +14,6 @@
* limitations under the License.
*/
import 'package:meta/meta.dart';
import 'data_types.dart';
import 'document.dart';
import 'function.dart';
... ... @@ -28,22 +26,16 @@ enum PdfShadingType { axial, radial }
class PdfShading extends PdfObject {
PdfShading(
PdfDocument pdfDocument, {
@required this.shadingType,
@required this.function,
@required this.start,
@required this.end,
required this.shadingType,
required this.function,
required this.start,
required this.end,
this.radius0,
this.radius1,
this.boundingBox,
this.extendStart = false,
this.extendEnd = false,
}) : assert(shadingType != null),
assert(function != null),
assert(start != null),
assert(end != null),
assert(extendStart != null),
assert(extendEnd != null),
super(pdfDocument);
}) : super(pdfDocument);
/// Name of the Shading object
String get name => '/S$objser';
... ... @@ -56,15 +48,15 @@ class PdfShading extends PdfObject {
final PdfPoint end;
final PdfRect boundingBox;
final PdfRect? boundingBox;
final bool extendStart;
final bool extendEnd;
final double radius0;
final double? radius0;
final double radius1;
final double? radius1;
@override
void prepare() {
... ... @@ -72,11 +64,11 @@ class PdfShading extends PdfObject {
params['/ShadingType'] = PdfNum(shadingType.index + 2);
if (boundingBox != null) {
params['/BBox'] = PdfArray.fromNum(<double>[
boundingBox.left,
boundingBox.bottom,
boundingBox.right,
boundingBox.top,
params['/BBox'] = PdfArray.fromNum(<double?>[
boundingBox!.left,
boundingBox!.bottom,
boundingBox!.right,
boundingBox!.top,
]);
}
params['/AntiAlias'] = const PdfBool(true);
... ... @@ -84,12 +76,12 @@ class PdfShading extends PdfObject {
if (shadingType == PdfShadingType.axial) {
params['/Coords'] =
PdfArray.fromNum(<double>[start.x, start.y, end.x, end.y]);
PdfArray.fromNum(<double?>[start.x, start.y, end.x, end.y]);
} else if (shadingType == PdfShadingType.radial) {
assert(radius0 != null);
assert(radius1 != null);
params['/Coords'] = PdfArray.fromNum(
<double>[start.x, start.y, radius0, end.x, end.y, radius1]);
<double?>[start.x, start.y, radius0, end.x, end.y, radius1]);
}
// params['/Domain'] = PdfArray.fromNum(<num>[0, 1]);
if (extendStart || extendEnd) {
... ...
... ... @@ -14,8 +14,6 @@
* limitations under the License.
*/
import 'package:meta/meta.dart';
import 'data_types.dart';
import 'document.dart';
import 'object.dart';
... ... @@ -26,10 +24,9 @@ enum PdfSigFlags { signaturesExist, appendOnly }
class PdfSignature extends PdfObject {
PdfSignature(
PdfDocument pdfDocument, {
@required this.crypto,
Set<PdfSigFlags> flags,
}) : assert(crypto != null),
flags = flags ?? const <PdfSigFlags>{PdfSigFlags.signaturesExist},
required this.crypto,
Set<PdfSigFlags>? flags,
}) : flags = flags ?? const <PdfSigFlags>{PdfSigFlags.signaturesExist},
super(pdfDocument, type: '/Sig');
final Set<PdfSigFlags> flags;
... ... @@ -40,8 +37,8 @@ class PdfSignature extends PdfObject {
.map<int>((PdfSigFlags e) => 1 >> e.index)
.reduce((int a, int b) => a | b);
int _offsetStart;
int _offsetEnd;
int? _offsetStart;
int? _offsetEnd;
@override
void write(PdfStream os) {
... ... @@ -64,5 +61,5 @@ abstract class PdfSignatureBase {
void preSign(PdfObject object, PdfDict params);
Future<void> sign(PdfObject object, PdfStream os, PdfDict params,
int offsetStart, int offsetEnd);
int? offsetStart, int? offsetEnd);
}
... ...
... ... @@ -16,8 +16,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import 'package:meta/meta.dart';
import 'data_types.dart';
import 'document.dart';
import 'function.dart';
... ... @@ -27,28 +25,24 @@ import 'rect.dart';
class PdfSoftMask {
PdfSoftMask(this.document,
{@required PdfRect boundingBox,
{required PdfRect boundingBox,
bool isolated = false,
bool knockout = false,
bool invert = false})
: assert(boundingBox != null),
assert(isolated != null),
assert(knockout != null),
assert(invert != null) {
bool invert = false}) {
_mask = PdfGraphicXObject(document);
_mask.params['/BBox'] = PdfArray.fromNum([
_mask!.params['/BBox'] = PdfArray.fromNum([
boundingBox.x,
boundingBox.y,
boundingBox.width,
boundingBox.height,
]);
if (isolated) {
_mask.params['/I'] = const PdfBool(true);
_mask!.params['/I'] = const PdfBool(true);
}
if (knockout) {
_mask.params['/K'] = const PdfBool(true);
_mask!.params['/K'] = const PdfBool(true);
}
_graphics = PdfGraphics(_mask, _mask.buf);
_graphics = PdfGraphics(_mask, _mask!.buf);
if (invert) {
_tr = PdfFunction(
... ... @@ -60,22 +54,22 @@ class PdfSoftMask {
final PdfDocument document;
PdfGraphicXObject _mask;
PdfGraphicXObject? _mask;
PdfGraphics _graphics;
PdfGraphics? _graphics;
PdfGraphics getGraphics() => _graphics;
PdfGraphics? getGraphics() => _graphics;
PdfBaseFunction _tr;
PdfBaseFunction? _tr;
PdfDict output() {
final params = PdfDict({
'/S': const PdfName('/Luminosity'),
'/G': _mask.ref(),
'/G': _mask!.ref(),
});
if (_tr != null) {
params['/TR'] = _tr.ref();
params['/TR'] = _tr!.ref();
}
return params;
... ...
... ... @@ -57,15 +57,15 @@ class PdfStream {
Uint8List output() => _stream.sublist(0, _offset);
void putString(String s) {
void putString(String? s) {
assert(() {
for (final codeUnit in s.codeUnits) {
for (final codeUnit in s!.codeUnits) {
if (codeUnit > 0x7f) {
return false;
}
}
return true;
}());
putBytes(s.codeUnits);
putBytes(s!.codeUnits);
}
}
... ...
... ... @@ -89,38 +89,39 @@ class TtfParser {
final UnmodifiableByteDataView bytes;
final Map<String, int> tableOffsets = <String, int>{};
final Map<String, int> tableSize = <String, int>{};
String _fontName;
String? _fontName;
final Map<int, int> charToGlyphIndexMap = <int, int>{};
final List<int> glyphOffsets = <int>[];
final Map<int, PdfFontMetrics> glyphInfoMap = <int, PdfFontMetrics>{};
int get unitsPerEm => bytes.getUint16(tableOffsets[head_table] + 18);
int get unitsPerEm => bytes.getUint16(tableOffsets[head_table]! + 18);
int get xMin => bytes.getInt16(tableOffsets[head_table] + 36);
int get xMin => bytes.getInt16(tableOffsets[head_table]! + 36);
int get yMin => bytes.getInt16(tableOffsets[head_table] + 38);
int get yMin => bytes.getInt16(tableOffsets[head_table]! + 38);
int get xMax => bytes.getInt16(tableOffsets[head_table] + 40);
int get xMax => bytes.getInt16(tableOffsets[head_table]! + 40);
int get yMax => bytes.getInt16(tableOffsets[head_table] + 42);
int get yMax => bytes.getInt16(tableOffsets[head_table]! + 42);
int get indexToLocFormat => bytes.getInt16(tableOffsets[head_table] + 50);
int get indexToLocFormat => bytes.getInt16(tableOffsets[head_table]! + 50);
int get ascent => bytes.getInt16(tableOffsets[hhea_table] + 4);
int get ascent => bytes.getInt16(tableOffsets[hhea_table]! + 4);
int get descent => bytes.getInt16(tableOffsets[hhea_table] + 6);
int get descent => bytes.getInt16(tableOffsets[hhea_table]! + 6);
int get numOfLongHorMetrics => bytes.getUint16(tableOffsets[hhea_table] + 34);
int get numOfLongHorMetrics =>
bytes.getUint16(tableOffsets[hhea_table]! + 34);
int get numGlyphs => bytes.getUint16(tableOffsets[maxp_table] + 4);
int get numGlyphs => bytes.getUint16(tableOffsets[maxp_table]! + 4);
String get fontName => _fontName;
String? get fontName => _fontName;
bool get unicode => bytes.getUint32(0) == 0x10000;
// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html
void _parseFontName() {
final basePosition = tableOffsets[name_table];
final basePosition = tableOffsets[name_table]!;
final count = bytes.getUint16(basePosition + 2);
final stringOffset = bytes.getUint16(basePosition + 4);
var pos = basePosition + 6;
... ... @@ -153,7 +154,7 @@ class TtfParser {
}
void _parseCMap() {
final basePosition = tableOffsets[cmap_table];
final basePosition = tableOffsets[cmap_table]!;
final numSubTables = bytes.getUint16(basePosition + 2);
for (var i = 0; i < numSubTables; i++) {
final offset = bytes.getUint32(basePosition + i * 8 + 8);
... ... @@ -262,11 +263,11 @@ class TtfParser {
final numGlyphs = this.numGlyphs;
if (indexToLocFormat == 0) {
for (var i = 0; i < numGlyphs; i++) {
glyphOffsets.add(bytes.getUint16(basePosition + i * 2) * 2);
glyphOffsets.add(bytes.getUint16(basePosition! + i * 2) * 2);
}
} else {
for (var i = 0; i < numGlyphs; i++) {
glyphOffsets.add(bytes.getUint32(basePosition + i * 4));
glyphOffsets.add(bytes.getUint32(basePosition! + i * 4));
}
}
}
... ... @@ -274,14 +275,14 @@ class TtfParser {
/// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html
void _parseGlyphs() {
final baseOffset = tableOffsets[glyf_table];
final hmtxOffset = tableOffsets[hmtx_table];
final hmtxOffset = tableOffsets[hmtx_table]!;
final unitsPerEm = this.unitsPerEm;
final numOfLongHorMetrics = this.numOfLongHorMetrics;
final defaultadvanceWidth =
bytes.getUint16(hmtxOffset + (numOfLongHorMetrics - 1) * 4);
var glyphIndex = 0;
for (var offset in glyphOffsets) {
final xMin = bytes.getInt16(baseOffset + offset + 2); // 2
final xMin = bytes.getInt16(baseOffset! + offset + 2); // 2
final yMin = bytes.getInt16(baseOffset + offset + 4); // 4
final xMax = bytes.getInt16(baseOffset + offset + 6); // 6
final yMax = bytes.getInt16(baseOffset + offset + 8); // 8
... ... @@ -309,10 +310,9 @@ class TtfParser {
/// http://stevehanov.ca/blog/?id=143
TtfGlyphInfo readGlyph(int index) {
assert(index != null);
assert(index < glyphOffsets.length);
final start = tableOffsets[glyf_table] + glyphOffsets[index];
final start = tableOffsets[glyf_table]! + glyphOffsets[index];
final numberOfContours = bytes.getInt16(start);
assert(numberOfContours >= -1);
... ...
... ... @@ -39,7 +39,7 @@ class TtfWriter {
return sum;
}
void _updateCompoundGlyph(TtfGlyphInfo glyph, Map<int, int> compoundMap) {
void _updateCompoundGlyph(TtfGlyphInfo glyph, Map<int, int?> compoundMap) {
const ARG_1_AND_2_ARE_WORDS = 1;
const MORE_COMPONENTS = 32;
... ... @@ -51,7 +51,7 @@ class TtfWriter {
while (flags & MORE_COMPONENTS != 0) {
flags = bytes.getUint16(offset);
final glyphIndex = bytes.getUint16(offset + 2);
bytes.setUint16(offset + 2, compoundMap[glyphIndex]);
bytes.setUint16(offset + 2, compoundMap[glyphIndex]!);
offset += (flags & ARG_1_AND_2_ARE_WORDS != 0) ? 8 : 6;
}
}
... ... @@ -79,7 +79,7 @@ class TtfWriter {
final glyph =
ttf.readGlyph(ttf.charToGlyphIndexMap[chars[index]] ?? 0).copy();
for (var g in glyph.compounds) {
compounds[g] = null;
compounds[g] = -1;
}
glyphsInfo.add(glyph);
}
... ... @@ -87,17 +87,18 @@ class TtfWriter {
// Add compound glyphs
for (var compound in compounds.keys) {
final index = glyphsInfo.firstWhere(
(TtfGlyphInfo glyph) => glyph.index == compound,
orElse: () => null);
if (index != null) {
compounds[compound] = glyphsInfo.indexOf(index);
assert(compounds[compound] >= 0, 'Unable to find the glyph');
} else {
compounds[compound] = glyphsInfo.length;
final glyph = ttf.readGlyph(compound);
assert(glyph.compounds.isEmpty, 'This is not a simple glyph');
glyphsInfo.add(glyph);
}
(TtfGlyphInfo glyph) => glyph.index == compound,
orElse: () {
final glyph = ttf.readGlyph(compound);
assert(glyph.compounds.isEmpty, 'This is not a simple glyph');
glyphsInfo.add(glyph);
return glyph;
},
);
compounds[compound] = glyphsInfo.indexOf(index);
assert(compounds[compound]! >= 0, 'Unable to find the glyph');
}
// Add one last empty glyph
... ... @@ -133,7 +134,7 @@ class TtfWriter {
}
{
final loca = tables[TtfParser.loca_table].buffer.asByteData();
final loca = tables[TtfParser.loca_table]!.buffer.asByteData();
var index = 0;
for (var glyph in glyphsInfo) {
if (ttf.indexToLocFormat == 0) {
... ... @@ -150,8 +151,8 @@ class TtfWriter {
{
// Head table
final start = ttf.tableOffsets[TtfParser.head_table];
final len = ttf.tableSize[TtfParser.head_table];
final start = ttf.tableOffsets[TtfParser.head_table]!;
final len = ttf.tableSize[TtfParser.head_table]!;
final head = Uint8List.fromList(
ttf.bytes.buffer.asUint8List(start, _wordAlign(len, 4)));
head.buffer.asByteData().setUint32(8, 0); // checkSumAdjustment
... ... @@ -161,8 +162,8 @@ class TtfWriter {
{
// MaxP table
final start = ttf.tableOffsets[TtfParser.maxp_table];
final len = ttf.tableSize[TtfParser.maxp_table];
final start = ttf.tableOffsets[TtfParser.maxp_table]!;
final len = ttf.tableSize[TtfParser.maxp_table]!;
final maxp = Uint8List.fromList(
ttf.bytes.buffer.asUint8List(start, _wordAlign(len, 4)));
maxp.buffer.asByteData().setUint16(4, glyphsInfo.length);
... ... @@ -172,8 +173,8 @@ class TtfWriter {
{
// HHEA table
final start = ttf.tableOffsets[TtfParser.hhea_table];
final len = ttf.tableSize[TtfParser.hhea_table];
final start = ttf.tableOffsets[TtfParser.hhea_table]!;
final len = ttf.tableSize[TtfParser.hhea_table]!;
final hhea = Uint8List.fromList(
ttf.bytes.buffer.asUint8List(start, _wordAlign(len, 4)));
hhea.buffer
... ... @@ -188,7 +189,7 @@ class TtfWriter {
// HMTX table
final len = 4 * glyphsInfo.length;
final hmtx = Uint8List(_wordAlign(len, 4));
final hmtxOffset = ttf.tableOffsets[TtfParser.hmtx_table];
final hmtxOffset = ttf.tableOffsets[TtfParser.hmtx_table]!;
final hmtxData = hmtx.buffer.asByteData();
final numOfLongHorMetrics = ttf.numOfLongHorMetrics;
final defaultadvanceWidth =
... ... @@ -262,7 +263,7 @@ class TtfWriter {
start.setUint32(12 + count * 16 + 4,
_calcTableChecksum(data.buffer.asByteData())); // checkSum
start.setUint32(12 + count * 16 + 8, offset); // offset
start.setUint32(12 + count * 16 + 12, tablesLength[name]); // length
start.setUint32(12 + count * 16 + 12, tablesLength[name]!); // length
offset += data.lengthInBytes;
count++;
});
... ...
... ... @@ -44,18 +44,18 @@ class PdfTtfFont extends PdfFont {
@override
String get subtype => font.unicode ? '/Type0' : super.subtype;
PdfUnicodeCmap unicodeCMap;
late PdfUnicodeCmap unicodeCMap;
PdfFontDescriptor descriptor;
late PdfFontDescriptor descriptor;
PdfObjectStream file;
late PdfObjectStream file;
PdfArrayObject widthsObject;
late PdfArrayObject widthsObject;
final TtfParser font;
@override
String get fontName => font.fontName;
String get fontName => font.fontName!;
@override
double get ascent => font.ascent.toDouble() / font.unitsPerEm;
... ... @@ -163,7 +163,7 @@ class PdfTtfFont extends PdfFont {
final runes = text.runes;
stream.putByte(0x3c);
for (int rune in runes) {
for (var rune in runes) {
var char = unicodeCMap.cmap.indexOf(rune);
if (char == -1) {
char = unicodeCMap.cmap.length;
... ...
... ... @@ -19,7 +19,7 @@ import 'document.dart';
import 'object_stream.dart';
class PdfXObject extends PdfObjectStream {
PdfXObject(PdfDocument pdfDocument, String subtype, {bool isBinary = false})
PdfXObject(PdfDocument pdfDocument, String? subtype, {bool isBinary = false})
: super(pdfDocument, type: '/XObject', isBinary: isBinary) {
if (subtype != null) {
params['/Subtype'] = PdfName(subtype);
... ...
... ... @@ -28,24 +28,24 @@ enum SvgTextAnchor { start, middle, end }
@immutable
class SvgBrush {
const SvgBrush({
@required this.opacity,
@required this.fill,
@required this.fillEvenOdd,
@required this.fillOpacity,
@required this.stroke,
@required this.strokeOpacity,
@required this.strokeWidth,
@required this.strokeDashArray,
@required this.strokeDashOffset,
@required this.strokeLineCap,
@required this.strokeLineJoin,
@required this.strokeMiterLimit,
@required this.fontFamily,
@required this.fontSize,
@required this.fontStyle,
@required this.fontWeight,
@required this.textAnchor,
@required this.blendMode,
required this.opacity,
required this.fill,
required this.fillEvenOdd,
required this.fillOpacity,
required this.stroke,
required this.strokeOpacity,
required this.strokeWidth,
required this.strokeDashArray,
required this.strokeDashOffset,
required this.strokeLineCap,
required this.strokeLineJoin,
required this.strokeMiterLimit,
required this.fontFamily,
required this.fontSize,
required this.fontStyle,
required this.fontWeight,
required this.textAnchor,
required this.blendMode,
this.mask,
});
... ... @@ -160,41 +160,41 @@ class SvgBrush {
'end': SvgTextAnchor.end,
};
final double opacity;
final SvgColor fill;
final bool fillEvenOdd;
final double fillOpacity;
final SvgColor stroke;
final double strokeOpacity;
final SvgNumeric strokeWidth;
final List<double> strokeDashArray;
final double strokeDashOffset;
final PdfLineCap strokeLineCap;
final PdfLineJoin strokeLineJoin;
final double strokeMiterLimit;
final SvgNumeric fontSize;
final String fontFamily;
final String fontStyle;
final String fontWeight;
final SvgTextAnchor textAnchor;
final PdfBlendMode blendMode;
final SvgMaskPath mask;
final double? opacity;
final SvgColor? fill;
final bool? fillEvenOdd;
final double? fillOpacity;
final SvgColor? stroke;
final double? strokeOpacity;
final SvgNumeric? strokeWidth;
final List<double>? strokeDashArray;
final double? strokeDashOffset;
final PdfLineCap? strokeLineCap;
final PdfLineJoin? strokeLineJoin;
final double? strokeMiterLimit;
final SvgNumeric? fontSize;
final String? fontFamily;
final String? fontStyle;
final String? fontWeight;
final SvgTextAnchor? textAnchor;
final PdfBlendMode? blendMode;
final SvgMaskPath? mask;
SvgBrush merge(SvgBrush other) {
SvgBrush merge(SvgBrush? other) {
if (other == null) {
return this;
}
var _fill = other.fill ?? fill;
if (_fill.inherit) {
_fill = fill.merge(other.fill);
if (_fill?.inherit ?? false) {
_fill = fill!.merge(other.fill!);
}
var _stroke = other.stroke ?? stroke;
if (_stroke.inherit) {
_stroke = stroke.merge(other.stroke);
if (_stroke?.inherit ?? false) {
_stroke = stroke!.merge(other.stroke!);
}
return SvgBrush(
... ... @@ -221,25 +221,25 @@ class SvgBrush {
}
SvgBrush copyWith({
double opacity,
SvgColor fill,
bool fillEvenOdd,
double fillOpacity,
SvgColor stroke,
double strokeOpacity,
SvgNumeric strokeWidth,
List<double> strokeDashArray,
double strokeDashOffset,
PdfLineCap strokeLineCap,
PdfLineJoin strokeLineJoin,
double strokeMiterLimit,
SvgNumeric fontSize,
String fontFamily,
String fontStyle,
String fontWeight,
SvgTextAnchor textAnchor,
PdfBlendMode blendMode,
SvgMaskPath mask,
double? opacity,
SvgColor? fill,
bool? fillEvenOdd,
double? fillOpacity,
SvgColor? stroke,
double? strokeOpacity,
SvgNumeric? strokeWidth,
List<double>? strokeDashArray,
double? strokeDashOffset,
PdfLineCap? strokeLineCap,
PdfLineJoin? strokeLineJoin,
double? strokeMiterLimit,
SvgNumeric? fontSize,
String? fontFamily,
String? fontStyle,
String? fontWeight,
SvgTextAnchor? textAnchor,
PdfBlendMode? blendMode,
SvgMaskPath? mask,
}) {
return SvgBrush(
opacity: opacity ?? this.opacity,
... ...
... ... @@ -33,7 +33,7 @@ class SvgClipPath {
return const SvgClipPath(null, true, null);
}
Iterable<SvgOperation> children;
Iterable<SvgOperation?> children;
if (clipPathAttr.startsWith('url(#')) {
final id = clipPathAttr.substring(5, clipPathAttr.lastIndexOf(')'));
... ... @@ -41,7 +41,7 @@ class SvgClipPath {
if (clipPath != null) {
children = clipPath.children
.whereType<XmlElement>()
.map<SvgOperation>((c) => SvgOperation.fromXml(c, painter, brush));
.map<SvgOperation?>((c) => SvgOperation.fromXml(c, painter, brush));
return SvgClipPath(children, false, painter);
}
}
... ... @@ -49,11 +49,11 @@ class SvgClipPath {
return const SvgClipPath(null, true, null);
}
final Iterable<SvgOperation> children;
final Iterable<SvgOperation?>? children;
final bool isEmpty;
final SvgPainter painter;
final SvgPainter? painter;
bool get isNotEmpty => !isEmpty;
... ... @@ -62,8 +62,8 @@ class SvgClipPath {
return;
}
for (final child in children) {
child.draw(canvas);
for (final child in children!) {
child!.draw(canvas);
}
canvas.clipPath();
}
... ...
... ... @@ -29,7 +29,7 @@ class SvgColor {
this.inherit = false,
});
factory SvgColor.fromXml(String color, SvgPainter painter) {
factory SvgColor.fromXml(String? color, SvgPainter painter) {
if (color == null) {
return inherited;
}
... ... @@ -93,7 +93,7 @@ class SvgColor {
if (color.toLowerCase().startsWith('url(#')) {
final gradient =
painter.parser.findById(color.substring(5, color.indexOf(')')));
painter.parser.findById(color.substring(5, color.indexOf(')')))!;
if (gradient.name.local == 'linearGradient') {
return SvgLinearGradient.fromXml(gradient, painter);
}
... ... @@ -116,9 +116,9 @@ class SvgColor {
static const none = SvgColor();
static const inherited = SvgColor(inherit: true);
final PdfColor color;
final PdfColor? color;
final double opacity;
final double? opacity;
final bool inherit;
... ...
... ... @@ -39,11 +39,11 @@ abstract class SvgGradient extends SvgColor {
assert(stops.length == opacityList.length),
super();
final GradientUnits gradientUnits;
final GradientUnits? gradientUnits;
final SvgTransform transform;
final List<PdfColor> colors;
final List<PdfColor?> colors;
final List<double> stops;
... ... @@ -53,7 +53,7 @@ abstract class SvgGradient extends SvgColor {
bool get isEmpty => colors.isEmpty;
PdfPattern buildGradient(
SvgOperation op, PdfGraphics canvas, List<PdfColor> colors);
SvgOperation op, PdfGraphics canvas, List<PdfColor?> colors);
@override
void setFillColor(SvgOperation op, PdfGraphics canvas) {
... ... @@ -73,7 +73,7 @@ abstract class SvgGradient extends SvgColor {
softMask: mask,
),
);
final maskCanvas = mask.getGraphics();
final maskCanvas = mask.getGraphics()!;
maskCanvas.drawBox(op.boundingBox());
maskCanvas.setFillPattern(
buildGradient(
... ... @@ -99,13 +99,13 @@ abstract class SvgGradient extends SvgColor {
class SvgLinearGradient extends SvgGradient {
const SvgLinearGradient(
GradientUnits gradientUnits,
GradientUnits? gradientUnits,
this.x1,
this.y1,
this.x2,
this.y2,
SvgTransform transform,
List<PdfColor> colors,
List<PdfColor?> colors,
List<double> stops,
List<double> opacityList)
: super(gradientUnits, transform, colors, stops, opacityList);
... ... @@ -116,7 +116,7 @@ class SvgLinearGradient extends SvgGradient {
final x2 = SvgParser.getNumeric(element, 'x2', null)?.sizeValue;
final y2 = SvgParser.getNumeric(element, 'y2', null)?.sizeValue;
final colors = <PdfColor>[];
final colors = <PdfColor?>[];
final stops = <double>[];
final opacityList = <double>[];
... ... @@ -127,15 +127,15 @@ class SvgLinearGradient extends SvgGradient {
final color = SvgColor.fromXml(
child.getAttribute('stop-color') ?? 'black', painter);
final opacity =
SvgParser.getDouble(child, 'stop-opacity', defaultValue: 1);
final stop = SvgParser.getNumeric(child, 'offset', null, defaultValue: 0)
SvgParser.getDouble(child, 'stop-opacity', defaultValue: 1)!;
final stop = SvgParser.getNumeric(child, 'offset', null, defaultValue: 0)!
.sizeValue;
colors.add(color.color);
stops.add(stop);
opacityList.add(opacity);
}
GradientUnits gradientUnits;
GradientUnits? gradientUnits;
switch (element.getAttribute('gradientUnits')) {
case 'userSpaceOnUse':
gradientUnits = GradientUnits.userSpaceOnUse;
... ... @@ -172,10 +172,10 @@ class SvgLinearGradient extends SvgGradient {
return result;
}
final double x1;
final double y1;
final double x2;
final double y2;
final double? x1;
final double? y1;
final double? x2;
final double? y2;
SvgLinearGradient mergeWith(SvgLinearGradient other) {
return SvgLinearGradient(
... ... @@ -193,7 +193,7 @@ class SvgLinearGradient extends SvgGradient {
@override
PdfPattern buildGradient(
SvgOperation op, PdfGraphics canvas, List<PdfColor> colors) {
SvgOperation op, PdfGraphics canvas, List<PdfColor?> colors) {
final mat = canvas.getTransform();
if (gradientUnits != GradientUnits.userSpaceOnUse) {
... ... @@ -204,7 +204,7 @@ class SvgLinearGradient extends SvgGradient {
}
if (transform.isNotEmpty) {
mat.multiply(transform.matrix);
mat.multiply(transform.matrix!);
}
return PdfShadingPattern(
... ... @@ -233,7 +233,7 @@ class SvgLinearGradient extends SvgGradient {
class SvgRadialGradient extends SvgGradient {
const SvgRadialGradient(
GradientUnits gradientUnits,
GradientUnits? gradientUnits,
this.r,
this.cx,
this.cy,
... ... @@ -241,26 +241,26 @@ class SvgRadialGradient extends SvgGradient {
this.fx,
this.fy,
SvgTransform transform,
List<PdfColor> colors,
List<PdfColor?> colors,
List<double> stops,
List<double> opacityList,
) : super(gradientUnits, transform, colors, stops, opacityList);
factory SvgRadialGradient.fromXml(XmlElement element, SvgPainter painter) {
final r =
SvgParser.getNumeric(element, 'r', null, defaultValue: .5).sizeValue;
SvgParser.getNumeric(element, 'r', null, defaultValue: .5)!.sizeValue;
final cx =
SvgParser.getNumeric(element, 'cx', null, defaultValue: .5).sizeValue;
SvgParser.getNumeric(element, 'cx', null, defaultValue: .5)!.sizeValue;
final cy =
SvgParser.getNumeric(element, 'cy', null, defaultValue: .5).sizeValue;
SvgParser.getNumeric(element, 'cy', null, defaultValue: .5)!.sizeValue;
final fr =
SvgParser.getNumeric(element, 'fr', null, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'fr', null, defaultValue: 0)!.sizeValue;
final fx =
SvgParser.getNumeric(element, 'fx', null, defaultValue: cx).sizeValue;
SvgParser.getNumeric(element, 'fx', null, defaultValue: cx)!.sizeValue;
final fy =
SvgParser.getNumeric(element, 'fy', null, defaultValue: cy).sizeValue;
SvgParser.getNumeric(element, 'fy', null, defaultValue: cy)!.sizeValue;
final colors = <PdfColor>[];
final colors = <PdfColor?>[];
final stops = <double>[];
final opacityList = <double>[];
... ... @@ -272,14 +272,14 @@ class SvgRadialGradient extends SvgGradient {
child.getAttribute('stop-color') ?? 'black', painter);
final opacity =
SvgParser.getDouble(child, 'stop-opacity', defaultValue: 1);
final stop = SvgParser.getNumeric(child, 'offset', null, defaultValue: 0)
final stop = SvgParser.getNumeric(child, 'offset', null, defaultValue: 0)!
.sizeValue;
colors.add(color.color);
stops.add(stop);
opacityList.add(opacity);
opacityList.add(opacity!);
}
GradientUnits gradientUnits;
GradientUnits? gradientUnits;
switch (element.getAttribute('gradientUnits')) {
case 'userSpaceOnUse':
gradientUnits = GradientUnits.userSpaceOnUse;
... ... @@ -317,12 +317,12 @@ class SvgRadialGradient extends SvgGradient {
return result;
}
final double r;
final double cx;
final double cy;
final double fr;
final double fx;
final double fy;
final double? r;
final double? cx;
final double? cy;
final double? fr;
final double? fx;
final double? fy;
SvgRadialGradient mergeWith(SvgRadialGradient other) {
return SvgRadialGradient(
... ... @@ -342,7 +342,7 @@ class SvgRadialGradient extends SvgGradient {
@override
PdfPattern buildGradient(
SvgOperation op, PdfGraphics canvas, List<PdfColor> colors) {
SvgOperation op, PdfGraphics canvas, List<PdfColor?> colors) {
final mat = canvas.getTransform();
if (gradientUnits != GradientUnits.userSpaceOnUse) {
... ... @@ -353,7 +353,7 @@ class SvgRadialGradient extends SvgGradient {
}
if (transform.isNotEmpty) {
mat.multiply(transform.matrix);
mat.multiply(transform.matrix!);
}
return PdfShadingPattern(
... ...
... ... @@ -41,9 +41,9 @@ class SvgGroup extends SvgOperation {
final children = element.children
.whereType<XmlElement>()
.where((element) => element.name.local != 'symbol')
.map<SvgOperation>(
.map<SvgOperation?>(
(child) => SvgOperation.fromXml(child, painter, _brush))
.where((element) => element != null);
.whereType<SvgOperation>();
return SvgGroup(
children,
... ...
... ... @@ -49,17 +49,17 @@ class SvgImg extends SvgOperation {
final _brush = SvgBrush.fromXml(element, brush, painter);
final width =
SvgParser.getNumeric(element, 'width', _brush, defaultValue: 0)
SvgParser.getNumeric(element, 'width', _brush, defaultValue: 0)!
.sizeValue;
final height =
SvgParser.getNumeric(element, 'height', _brush, defaultValue: 0)
SvgParser.getNumeric(element, 'height', _brush, defaultValue: 0)!
.sizeValue;
final x =
SvgParser.getNumeric(element, 'x', _brush, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'x', _brush, defaultValue: 0)!.sizeValue;
final y =
SvgParser.getNumeric(element, 'y', _brush, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'y', _brush, defaultValue: 0)!.sizeValue;
PdfImage image;
PdfImage? image;
final hrefAttr = element.getAttribute('href') ??
element.getAttribute('href', namespace: 'http://www.w3.org/1999/xlink');
... ... @@ -71,7 +71,7 @@ class SvgImg extends SvgOperation {
final b = px.substring(7).replaceAll(RegExp(r'\s'), '');
final bytes = base64.decode(b);
final img = im.decodeImage(bytes);
final img = im.decodeImage(bytes)!;
image = PdfImage(
painter.document,
image: img.data.buffer.asUint8List(),
... ... @@ -103,7 +103,7 @@ class SvgImg extends SvgOperation {
final double height;
final PdfImage image;
final PdfImage? image;
@override
void paintShape(PdfGraphics canvas) {
... ... @@ -111,8 +111,8 @@ class SvgImg extends SvgOperation {
return;
}
final sx = width / image.width;
final sy = height / image.height;
final sx = width / image!.width;
final sy = height / image!.height;
canvas
..setTransform(
... ... @@ -120,7 +120,7 @@ class SvgImg extends SvgOperation {
..translate(x, y + height, 0)
..scale(sx, -sy),
)
..drawImage(image, 0, 0);
..drawImage(image!, 0, 0);
}
@override
... ...
... ... @@ -26,21 +26,21 @@ import 'painter.dart';
class SvgMaskPath {
const SvgMaskPath(this.children, this.painter);
static SvgMaskPath fromXml(
static SvgMaskPath? fromXml(
XmlElement element, SvgPainter painter, SvgBrush brush) {
final maskPathAttr = element.getAttribute('mask');
if (maskPathAttr == null) {
return null;
}
Iterable<SvgOperation> children;
Iterable<SvgOperation?> children;
if (maskPathAttr.startsWith('url(#')) {
final id = maskPathAttr.substring(5, maskPathAttr.lastIndexOf(')'));
final maskPath = painter.parser.findById(id);
if (maskPath != null) {
final maskBrush = SvgBrush.fromXml(maskPath, brush, painter);
children = maskPath.children.whereType<XmlElement>().map<SvgOperation>(
children = maskPath.children.whereType<XmlElement>().map<SvgOperation?>(
(c) => SvgOperation.fromXml(c, painter, maskBrush));
return SvgMaskPath(children, painter);
}
... ... @@ -49,7 +49,7 @@ class SvgMaskPath {
return null;
}
final Iterable<SvgOperation> children;
final Iterable<SvgOperation?> children;
final SvgPainter painter;
... ... @@ -63,7 +63,7 @@ class SvgMaskPath {
// maskCanvas.setTransform(canvas.getTransform());
for (final child in children) {
child.paint(maskCanvas);
child!.paint(maskCanvas!);
}
canvas.setGraphicState(PdfGraphicState(softMask: mask));
... ...
... ... @@ -32,7 +32,7 @@ import 'use.dart';
abstract class SvgOperation {
SvgOperation(this.brush, this.clip, this.transform, this.painter);
static SvgOperation fromXml(
static SvgOperation? fromXml(
XmlElement element, SvgPainter painter, SvgBrush brush) {
if (element.getAttribute('visibility') == 'hidden') {
return null;
... ... @@ -84,16 +84,16 @@ abstract class SvgOperation {
canvas.saveContext();
clip.apply(canvas);
if (transform.isNotEmpty) {
canvas.setTransform(transform.matrix);
canvas.setTransform(transform.matrix!);
}
if (brush.opacity < 1.0 || brush.blendMode != null) {
if (brush.opacity! < 1.0 || brush.blendMode != null) {
canvas.setGraphicState(PdfGraphicState(
opacity: brush.opacity == 1 ? null : brush.opacity,
blendMode: brush.blendMode,
));
}
if (brush.mask != null) {
brush.mask.apply(canvas);
brush.mask!.apply(canvas);
}
paintShape(canvas);
canvas.restoreContext();
... ... @@ -105,7 +105,7 @@ abstract class SvgOperation {
void draw(PdfGraphics canvas) {
canvas.saveContext();
if (transform.isNotEmpty) {
canvas.setTransform(transform.matrix);
canvas.setTransform(transform.matrix!);
}
drawShape(canvas);
canvas.restoreContext();
... ...
... ... @@ -31,7 +31,7 @@ class SvgPainter {
final SvgParser parser;
final PdfGraphics _canvas;
final PdfGraphics? _canvas;
final PdfDocument document;
... ... @@ -42,12 +42,12 @@ class SvgPainter {
parser.root,
this,
SvgBrush.defaultContext,
).paint(_canvas);
).paint(_canvas!);
}
final _fontCache = <String, Font>{};
Font getFontCache(String fontFamily, String fontStyle, String fontWeight) {
Font? getFontCache(String fontFamily, String fontStyle, String fontWeight) {
final cache = '$fontFamily-$fontStyle-$fontWeight';
if (!_fontCache.containsKey(cache)) {
... ...
... ... @@ -14,7 +14,6 @@
* limitations under the License.
*/
import 'package:meta/meta.dart';
import 'package:pdf/pdf.dart';
import 'package:xml/xml.dart';
... ... @@ -23,8 +22,7 @@ import 'brush.dart';
class SvgParser {
/// Create an SVG parser
factory SvgParser({@required XmlDocument xml}) {
assert(xml != null);
factory SvgParser({required XmlDocument xml}) {
final root = xml.rootElement;
final vbattr = root.getAttribute('viewBox');
... ... @@ -54,15 +52,15 @@ class SvgParser {
final PdfRect viewBox;
final double width;
final double? width;
final double height;
final double? height;
final XmlElement root;
static final _transformParameterRegExp = RegExp(r'[\w.-]+');
XmlElement findById(String id) {
XmlElement? findById(String id) {
try {
return root.descendants.whereType<XmlElement>().firstWhere(
(e) => e.getAttribute('id') == id,
... ... @@ -72,8 +70,8 @@ class SvgParser {
}
}
static double getDouble(XmlElement xml, String name,
{String namespace, double defaultValue = 0}) {
static double? getDouble(XmlElement xml, String name,
{String? namespace, double? defaultValue = 0}) {
final attr = xml.getAttribute(name, namespace: namespace);
if (attr == null) {
... ... @@ -83,8 +81,8 @@ class SvgParser {
return double.parse(attr);
}
static SvgNumeric getNumeric(XmlElement xml, String name, SvgBrush brush,
{String namespace, double defaultValue}) {
static SvgNumeric? getNumeric(XmlElement xml, String name, SvgBrush? brush,
{String? namespace, double? defaultValue}) {
final attr = xml.getAttribute(name, namespace: namespace);
if (attr == null) {
... ... @@ -94,21 +92,21 @@ class SvgParser {
return SvgNumeric(attr, brush);
}
static Iterable<SvgNumeric> splitNumeric(String parameters, SvgBrush brush) {
static Iterable<SvgNumeric> splitNumeric(String parameters, SvgBrush? brush) {
final parameterMatches = _transformParameterRegExp.allMatches(parameters);
return parameterMatches.map((m) => SvgNumeric(m.group(0), brush));
return parameterMatches.map((m) => SvgNumeric(m.group(0)!, brush));
}
static Iterable<double> splitDoubles(String parameters) {
final parameterMatches = _transformParameterRegExp.allMatches(parameters);
return parameterMatches.map((m) => double.parse(m.group(0)));
return parameterMatches.map((m) => double.parse(m.group(0)!));
}
static Iterable<int> splitIntegers(String parameters) {
final parameterMatches = _transformParameterRegExp.allMatches(parameters);
return parameterMatches.map((m) {
return int.parse(m.group(0));
return int.parse(m.group(0)!);
});
}
... ... @@ -121,8 +119,8 @@ class SvgParser {
continue;
}
final kv = RegExp(r'([\w-]+)\s*:\s*(.*)').allMatches(style).first;
final key = kv.group(1);
final value = kv.group(2);
final key = kv.group(1)!;
final value = kv.group(2)!;
element.setAttribute(key, value);
}
... ... @@ -142,21 +140,20 @@ enum SvgUnit {
}
class SvgNumeric {
factory SvgNumeric(String value, SvgBrush brush) {
factory SvgNumeric(String value, SvgBrush? brush) {
final r = RegExp(r'([-+]?[\d\.]+)\s*(px|pt|em|cm|mm|in|%|)')
.allMatches(value)
.first;
return SvgNumeric.value(
double.parse(r.group(1)), brush, _svgUnits[r.group(2)]);
double.parse(r.group(1)!), brush, _svgUnits[r.group(2)]!);
}
const SvgNumeric.value(
this.value,
this.brush, [
this.unit = SvgUnit.direct,
]) : assert(value != null),
assert(unit != null);
]);
static const _svgUnits = <String, SvgUnit>{
'px': SvgUnit.pixels,
... ... @@ -173,13 +170,12 @@ class SvgNumeric {
final SvgUnit unit;
final SvgBrush brush;
final SvgBrush? brush;
double get colorValue {
switch (unit) {
case SvgUnit.percent:
return value / 100.0;
break;
case SvgUnit.direct:
return value / 255.0;
default:
... ... @@ -191,7 +187,6 @@ class SvgNumeric {
switch (unit) {
case SvgUnit.percent:
return value / 100.0;
break;
case SvgUnit.direct:
case SvgUnit.pixels:
case SvgUnit.points:
... ... @@ -203,8 +198,7 @@ class SvgNumeric {
case SvgUnit.inch:
return value * PdfPageFormat.inch;
case SvgUnit.em:
return value * brush.fontSize.sizeValue;
return value * brush!.fontSize!.sizeValue;
}
throw Exception('Invalid size value $value ($unit)');
}
}
... ...
... ... @@ -64,20 +64,20 @@ class SvgPath extends SvgOperation {
final _brush = SvgBrush.fromXml(element, brush, painter);
final x =
SvgParser.getNumeric(element, 'x', _brush, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'x', _brush, defaultValue: 0)!.sizeValue;
final y =
SvgParser.getNumeric(element, 'y', _brush, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'y', _brush, defaultValue: 0)!.sizeValue;
final width =
SvgParser.getNumeric(element, 'width', _brush, defaultValue: 0)
SvgParser.getNumeric(element, 'width', _brush, defaultValue: 0)!
.sizeValue;
final height =
SvgParser.getNumeric(element, 'height', _brush, defaultValue: 0)
SvgParser.getNumeric(element, 'height', _brush, defaultValue: 0)!
.sizeValue;
var rx = SvgParser.getNumeric(element, 'rx', _brush)?.sizeValue;
var ry = SvgParser.getNumeric(element, 'ry', _brush)?.sizeValue;
ry ??= rx ?? 0;
rx ??= ry ?? 0;
rx ??= ry;
final topRight = rx != 0 || ry != 0 ? 'a $rx $ry 0 0 1 $rx $ry' : '';
final bottomRight = rx != 0 || ry != 0 ? 'a $rx $ry 0 0 1 ${-rx} $ry' : '';
final bottomLeft =
... ... @@ -102,9 +102,9 @@ class SvgPath extends SvgOperation {
) {
final _brush = SvgBrush.fromXml(element, brush, painter);
final cx = SvgParser.getNumeric(element, 'cx', _brush).sizeValue;
final cy = SvgParser.getNumeric(element, 'cy', _brush).sizeValue;
final r = SvgParser.getNumeric(element, 'r', _brush).sizeValue;
final cx = SvgParser.getNumeric(element, 'cx', _brush)!.sizeValue;
final cy = SvgParser.getNumeric(element, 'cy', _brush)!.sizeValue;
final r = SvgParser.getNumeric(element, 'r', _brush)!.sizeValue;
final d =
'M${cx - r},${cy}A$r,$r 0,0,0 ${cx + r},${cy}A$r,$r 0,0,0 ${cx - r},${cy}z';
... ... @@ -124,10 +124,10 @@ class SvgPath extends SvgOperation {
) {
final _brush = SvgBrush.fromXml(element, brush, painter);
final cx = SvgParser.getNumeric(element, 'cx', _brush).sizeValue;
final cy = SvgParser.getNumeric(element, 'cy', _brush).sizeValue;
final rx = SvgParser.getNumeric(element, 'rx', _brush).sizeValue;
final ry = SvgParser.getNumeric(element, 'ry', _brush).sizeValue;
final cx = SvgParser.getNumeric(element, 'cx', _brush)!.sizeValue;
final cy = SvgParser.getNumeric(element, 'cy', _brush)!.sizeValue;
final rx = SvgParser.getNumeric(element, 'rx', _brush)!.sizeValue;
final ry = SvgParser.getNumeric(element, 'ry', _brush)!.sizeValue;
final d =
'M${cx - rx},${cy}A$rx,$ry 0,0,0 ${cx + rx},${cy}A$rx,$ry 0,0,0 ${cx - rx},${cy}z';
... ... @@ -184,10 +184,10 @@ class SvgPath extends SvgOperation {
) {
final _brush = SvgBrush.fromXml(element, brush, painter);
final x1 = SvgParser.getNumeric(element, 'x1', _brush).sizeValue;
final y1 = SvgParser.getNumeric(element, 'y1', _brush).sizeValue;
final x2 = SvgParser.getNumeric(element, 'x2', _brush).sizeValue;
final y2 = SvgParser.getNumeric(element, 'y2', _brush).sizeValue;
final x1 = SvgParser.getNumeric(element, 'x1', _brush)!.sizeValue;
final y1 = SvgParser.getNumeric(element, 'y1', _brush)!.sizeValue;
final x2 = SvgParser.getNumeric(element, 'x2', _brush)!.sizeValue;
final y2 = SvgParser.getNumeric(element, 'y2', _brush)!.sizeValue;
final d = 'M$x1 $y1 $x2 $y2';
return SvgPath(
... ... @@ -203,34 +203,34 @@ class SvgPath extends SvgOperation {
@override
void paintShape(PdfGraphics canvas) {
if (brush.fill.isNotEmpty) {
brush.fill.setFillColor(this, canvas);
if (brush.fillOpacity < 1) {
if (brush.fill!.isNotEmpty) {
brush.fill!.setFillColor(this, canvas);
if (brush.fillOpacity! < 1) {
canvas
..saveContext()
..setGraphicState(PdfGraphicState(opacity: brush.fillOpacity));
}
canvas
..drawShape(d)
..fillPath(evenOdd: brush.fillEvenOdd);
if (brush.fillOpacity < 1) {
..fillPath(evenOdd: brush.fillEvenOdd!);
if (brush.fillOpacity! < 1) {
canvas.restoreContext();
}
}
if (brush.stroke.isNotEmpty) {
brush.stroke.setStrokeColor(this, canvas);
if (brush.strokeOpacity < 1) {
if (brush.stroke!.isNotEmpty) {
brush.stroke!.setStrokeColor(this, canvas);
if (brush.strokeOpacity! < 1) {
canvas.setGraphicState(PdfGraphicState(opacity: brush.strokeOpacity));
}
canvas
..drawShape(d)
..setLineCap(brush.strokeLineCap)
..setLineJoin(brush.strokeLineJoin)
..setMiterLimit(math.max(1.0, brush.strokeMiterLimit))
..setLineCap(brush.strokeLineCap!)
..setLineJoin(brush.strokeLineJoin!)
..setMiterLimit(math.max(1.0, brush.strokeMiterLimit!))
..setLineDashPattern(
brush.strokeDashArray, brush.strokeDashOffset.toInt())
..setLineWidth(brush.strokeWidth.sizeValue)
brush.strokeDashArray!, brush.strokeDashOffset!.toInt())
..setLineWidth(brush.strokeWidth!.sizeValue)
..strokePath();
}
}
... ...
... ... @@ -39,9 +39,9 @@ class SvgSymbol extends SvgGroup {
final children = element.children
.whereType<XmlElement>()
.map<SvgOperation>(
.map<SvgOperation?>(
(child) => SvgOperation.fromXml(child, painter, _brush))
.where((element) => element != null);
.whereType<SvgOperation>();
return SvgSymbol(
children,
... ...
... ... @@ -52,9 +52,9 @@ class SvgText extends SvgOperation {
final _brush = SvgBrush.fromXml(element, brush, painter);
final dx =
SvgParser.getNumeric(element, 'dx', _brush, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'dx', _brush, defaultValue: 0)!.sizeValue;
final dy =
SvgParser.getNumeric(element, 'dy', _brush, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'dy', _brush, defaultValue: 0)!.sizeValue;
final x = SvgParser.getNumeric(element, 'x', _brush)?.sizeValue;
final y = SvgParser.getNumeric(element, 'y', _brush)?.sizeValue;
... ... @@ -65,12 +65,12 @@ class SvgText extends SvgOperation {
.trim();
final font = painter.getFontCache(
_brush.fontFamily, _brush.fontStyle, _brush.fontWeight);
final pdfFont = font.getFont(Context(document: painter.document));
final metrics = pdfFont.stringMetrics(text) * _brush.fontSize.sizeValue;
_brush.fontFamily!, _brush.fontStyle!, _brush.fontWeight!)!;
final pdfFont = font.getFont(Context(document: painter.document))!;
final metrics = pdfFont.stringMetrics(text) * _brush.fontSize!.sizeValue;
offset = PdfPoint((x ?? offset.x) + dx, (y ?? offset.y) + dy);
switch (_brush.textAnchor) {
switch (_brush.textAnchor!) {
case SvgTextAnchor.start:
break;
case SvgTextAnchor.middle:
... ... @@ -85,7 +85,7 @@ class SvgText extends SvgOperation {
final tspan = element.children.whereType<XmlElement>().map<SvgText>((e) {
final child = SvgText.fromXml(e, painter, _brush, childOffset);
childOffset = PdfPoint(child.x + child.dx, child.y);
childOffset = PdfPoint(child.x! + child.dx, child.y!);
return child;
});
... ... @@ -104,9 +104,9 @@ class SvgText extends SvgOperation {
);
}
final double x;
final double? x;
final double y;
final double? y;
final double dx;
... ... @@ -124,33 +124,33 @@ class SvgText extends SvgOperation {
..saveContext()
..setTransform(Matrix4.identity()
..scale(1.0, -1.0)
..translate(x, -y));
..translate(x, -y!));
if (brush.fill.isNotEmpty) {
brush.fill.setFillColor(this, canvas);
if (brush.fillOpacity < 1) {
if (brush.fill!.isNotEmpty) {
brush.fill!.setFillColor(this, canvas);
if (brush.fillOpacity! < 1) {
canvas
..saveContext()
..setGraphicState(PdfGraphicState(opacity: brush.fillOpacity));
}
canvas.drawString(font, brush.fontSize.sizeValue, text, 0, 0);
if (brush.fillOpacity < 1) {
canvas.drawString(font, brush.fontSize!.sizeValue, text, 0, 0);
if (brush.fillOpacity! < 1) {
canvas.restoreContext();
}
}
if (brush.stroke.isNotEmpty) {
if (brush.stroke!.isNotEmpty) {
if (brush.strokeWidth != null) {
canvas.setLineWidth(brush.strokeWidth.sizeValue);
canvas.setLineWidth(brush.strokeWidth!.sizeValue);
}
if (brush.strokeDashArray != null) {
canvas.setLineDashPattern(brush.strokeDashArray);
canvas.setLineDashPattern(brush.strokeDashArray!);
}
if (brush.strokeOpacity < 1) {
if (brush.strokeOpacity! < 1) {
canvas.setGraphicState(PdfGraphicState(opacity: brush.strokeOpacity));
}
brush.stroke.setStrokeColor(this, canvas);
canvas.drawString(font, brush.fontSize.sizeValue, text, 0, 0,
brush.stroke!.setStrokeColor(this, canvas);
canvas.drawString(font, brush.fontSize!.sizeValue, text, 0, 0,
mode: PdfTextRenderingMode.stroke);
}
... ... @@ -167,8 +167,8 @@ class SvgText extends SvgOperation {
..saveContext()
..setTransform(Matrix4.identity()
..scale(1.0, -1.0)
..translate(x, -y))
..drawString(font, brush.fontSize.sizeValue, text, 0, 0,
..translate(x, -y!))
..drawString(font, brush.fontSize!.sizeValue, text, 0, 0,
mode: PdfTextRenderingMode.clip)
..restoreContext();
... ...
... ... @@ -26,11 +26,7 @@ class SvgTransform {
return SvgTransform.fromString(element.getAttribute('transform'));
}
factory SvgTransform.fromString(String transform) {
if (transform == null) {
return none;
}
factory SvgTransform.fromString(String? transform) {
if (transform == null) {
return none;
}
... ... @@ -39,7 +35,7 @@ class SvgTransform {
for (final m in _transformRegExp.allMatches(transform)) {
final name = m.group(1);
final parameterList = SvgParser.splitDoubles(m.group(2)).toList();
final parameterList = SvgParser.splitDoubles(m.group(2)!).toList();
switch (name) {
case 'matrix':
... ... @@ -96,7 +92,7 @@ class SvgTransform {
return SvgTransform(mat);
}
final Matrix4 matrix;
final Matrix4? matrix;
bool get isEmpty => matrix == null;
... ...
... ... @@ -46,17 +46,17 @@ class SvgUse extends SvgOperation {
final _brush = SvgBrush.fromXml(element, brush, painter);
final width =
SvgParser.getNumeric(element, 'width', _brush, defaultValue: 0)
SvgParser.getNumeric(element, 'width', _brush, defaultValue: 0)!
.sizeValue;
final height =
SvgParser.getNumeric(element, 'height', _brush, defaultValue: 0)
SvgParser.getNumeric(element, 'height', _brush, defaultValue: 0)!
.sizeValue;
final x =
SvgParser.getNumeric(element, 'x', _brush, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'x', _brush, defaultValue: 0)!.sizeValue;
final y =
SvgParser.getNumeric(element, 'y', _brush, defaultValue: 0).sizeValue;
SvgParser.getNumeric(element, 'y', _brush, defaultValue: 0)!.sizeValue;
SvgOperation href;
SvgOperation? href;
final hrefAttr = element.getAttribute('href') ??
element.getAttribute('href', namespace: 'http://www.w3.org/1999/xlink');
... ... @@ -88,7 +88,7 @@ class SvgUse extends SvgOperation {
final double height;
final SvgOperation href;
final SvgOperation? href;
@override
void paintShape(PdfGraphics canvas) {
... ... @@ -107,5 +107,5 @@ class SvgUse extends SvgOperation {
}
@override
PdfRect boundingBox() => href.boundingBox();
PdfRect boundingBox() => href!.boundingBox();
}
... ...