From 985d3159e262d04a0f3a2c0826f0b077a9577b63 Mon Sep 17 00:00:00 2001 From: Tyler Denniston Date: Sat, 14 Sep 2024 15:39:48 -0400 Subject: [PATCH 1/3] Add support for custom fonts in SVGs. This adds the interface `SvgCustomFonts` and a corresponding parameter to the SvgImage widget. This provides a mechanism to support SVGs that have known fonts referenced in them. Closes #1731. --- pdf/lib/src/svg/painter.dart | 13 +++++++++++-- pdf/lib/src/widgets/svg.dart | 10 ++++++++++ pdf/test/widget_svg_test.dart | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/pdf/lib/src/svg/painter.dart b/pdf/lib/src/svg/painter.dart index 3f4cd0c4..18ec77fe 100644 --- a/pdf/lib/src/svg/painter.dart +++ b/pdf/lib/src/svg/painter.dart @@ -16,6 +16,7 @@ import '../../pdf.dart'; import '../widgets/font.dart'; +import '../widgets/svg.dart'; import 'brush.dart'; import 'color.dart'; import 'group.dart'; @@ -26,8 +27,9 @@ class SvgPainter { this.parser, this._canvas, this.document, - this.boundingBox, - ); + this.boundingBox, { + this.customFonts, + }); final SvgParser parser; @@ -37,6 +39,8 @@ class SvgPainter { final PdfRect boundingBox; + final SvgCustomFonts? customFonts; + void paint() { final brush = parser.colorFilter == null ? SvgBrush.defaultContext @@ -59,6 +63,11 @@ class SvgPainter { } Font getFont(String fontFamily, String fontStyle, String fontWeight) { + final customFont = customFonts?.getFont(fontFamily, fontStyle, fontWeight); + if (customFont != null) { + return customFont; + } + switch (fontFamily) { case 'serif': switch (fontStyle) { diff --git a/pdf/lib/src/widgets/svg.dart b/pdf/lib/src/widgets/svg.dart index d6968c81..c8f3a17c 100644 --- a/pdf/lib/src/widgets/svg.dart +++ b/pdf/lib/src/widgets/svg.dart @@ -32,6 +32,7 @@ class SvgImage extends Widget { double? width, double? height, PdfColor? colorFilter, + SvgCustomFonts? customFonts, }) { final xml = XmlDocument.parse(svg); final parser = SvgParser( @@ -46,6 +47,7 @@ class SvgImage extends Widget { clip, width, height, + customFonts, ); } @@ -56,6 +58,7 @@ class SvgImage extends Widget { this.clip, this.width, this.height, + this.customFonts, ); final SvgParser _svgParser; @@ -70,6 +73,8 @@ class SvgImage extends Widget { final double? height; + final SvgCustomFonts? customFonts; + late FittedSizes sizes; @override @@ -126,6 +131,7 @@ class SvgImage extends Widget { context.page.pageFormat.width, context.page.pageFormat.height, ), + customFonts: customFonts, ); painter.paint(); context.canvas.restoreContext(); @@ -154,3 +160,7 @@ class DecorationSvgImage extends DecorationGraphic { ); } } + +abstract class SvgCustomFonts { + Font? getFont(String fontFamily, String fontStyle, String fontWeight); +} diff --git a/pdf/test/widget_svg_test.dart b/pdf/test/widget_svg_test.dart index 83d53230..19361dd6 100644 --- a/pdf/test/widget_svg_test.dart +++ b/pdf/test/widget_svg_test.dart @@ -100,6 +100,18 @@ void main() { ); }); + test('SVG Widgets Text custom fonts', () { + pdf.addPage( + Page( + build: (context) => SvgImage( + svg: + 'Hello, PDF', + customFonts: _CustomFonts(), + ), + ), + ); + }); + test('SVG Widgets Barcode', () { pdf.addPage( Page( @@ -200,3 +212,10 @@ void main() { await file.writeAsBytes(await pdf.save()); }); } + +class _CustomFonts implements SvgCustomFonts { + @override + Font? getFont(String fontFamily, String fontStyle, String fontWeight) { + return null; + } +} From 1fab5760e9eb59a5017f300bc95d7f29e19487af Mon Sep 17 00:00:00 2001 From: Tyler Denniston Date: Sun, 22 Sep 2024 15:34:55 -0400 Subject: [PATCH 2/3] interface -> function --- pdf/lib/src/svg/painter.dart | 7 ++++--- pdf/lib/src/widgets/svg.dart | 15 +++++++-------- pdf/test/widget_svg_test.dart | 9 +-------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/pdf/lib/src/svg/painter.dart b/pdf/lib/src/svg/painter.dart index 18ec77fe..61d00049 100644 --- a/pdf/lib/src/svg/painter.dart +++ b/pdf/lib/src/svg/painter.dart @@ -28,7 +28,7 @@ class SvgPainter { this._canvas, this.document, this.boundingBox, { - this.customFonts, + this.customFontLookup, }); final SvgParser parser; @@ -39,7 +39,7 @@ class SvgPainter { final PdfRect boundingBox; - final SvgCustomFonts? customFonts; + final SvgCustomFontLookup? customFontLookup; void paint() { final brush = parser.colorFilter == null @@ -63,7 +63,8 @@ class SvgPainter { } Font getFont(String fontFamily, String fontStyle, String fontWeight) { - final customFont = customFonts?.getFont(fontFamily, fontStyle, fontWeight); + final customFont = + customFontLookup?.call(fontFamily, fontStyle, fontWeight); if (customFont != null) { return customFont; } diff --git a/pdf/lib/src/widgets/svg.dart b/pdf/lib/src/widgets/svg.dart index c8f3a17c..6ccc4e58 100644 --- a/pdf/lib/src/widgets/svg.dart +++ b/pdf/lib/src/widgets/svg.dart @@ -32,7 +32,7 @@ class SvgImage extends Widget { double? width, double? height, PdfColor? colorFilter, - SvgCustomFonts? customFonts, + SvgCustomFontLookup? customFontLookup, }) { final xml = XmlDocument.parse(svg); final parser = SvgParser( @@ -47,7 +47,7 @@ class SvgImage extends Widget { clip, width, height, - customFonts, + customFontLookup, ); } @@ -58,7 +58,7 @@ class SvgImage extends Widget { this.clip, this.width, this.height, - this.customFonts, + this.customFontLookup, ); final SvgParser _svgParser; @@ -73,7 +73,7 @@ class SvgImage extends Widget { final double? height; - final SvgCustomFonts? customFonts; + final SvgCustomFontLookup? customFontLookup; late FittedSizes sizes; @@ -131,7 +131,7 @@ class SvgImage extends Widget { context.page.pageFormat.width, context.page.pageFormat.height, ), - customFonts: customFonts, + customFontLookup: customFontLookup, ); painter.paint(); context.canvas.restoreContext(); @@ -161,6 +161,5 @@ class DecorationSvgImage extends DecorationGraphic { } } -abstract class SvgCustomFonts { - Font? getFont(String fontFamily, String fontStyle, String fontWeight); -} +typedef SvgCustomFontLookup = Font? Function( + String fontFamily, String fontStyle, String fontWeight); diff --git a/pdf/test/widget_svg_test.dart b/pdf/test/widget_svg_test.dart index 19361dd6..ddc4831d 100644 --- a/pdf/test/widget_svg_test.dart +++ b/pdf/test/widget_svg_test.dart @@ -106,7 +106,7 @@ void main() { build: (context) => SvgImage( svg: 'Hello, PDF', - customFonts: _CustomFonts(), + customFontLookup: (_, __, ___) => null, ), ), ); @@ -212,10 +212,3 @@ void main() { await file.writeAsBytes(await pdf.save()); }); } - -class _CustomFonts implements SvgCustomFonts { - @override - Font? getFont(String fontFamily, String fontStyle, String fontWeight) { - return null; - } -} From c3b012f8f899a91a97634b9590d901c0b6a80194 Mon Sep 17 00:00:00 2001 From: Tyler Denniston Date: Tue, 1 Oct 2024 13:55:18 -0400 Subject: [PATCH 3/3] improve test --- pdf/test/widget_svg_test.dart | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/pdf/test/widget_svg_test.dart b/pdf/test/widget_svg_test.dart index ddc4831d..c1fbc526 100644 --- a/pdf/test/widget_svg_test.dart +++ b/pdf/test/widget_svg_test.dart @@ -20,6 +20,8 @@ import 'package:pdf/pdf.dart'; import 'package:pdf/widgets.dart'; import 'package:test/test.dart'; +import 'utils.dart'; + late Document pdf; void main() { @@ -101,13 +103,26 @@ void main() { }); test('SVG Widgets Text custom fonts', () { + const customFamilyName1 = 'Test-Font-Family1'; + const customFamilyName2 = 'Test-Font-Family2'; + final customFont1 = loadFont('open-sans-bold.ttf'); + final customFont2 = loadFont('genyomintw.ttf'); pdf.addPage( Page( build: (context) => SvgImage( - svg: - 'Hello, PDF', - customFontLookup: (_, __, ___) => null, - ), + svg: + 'Custom fonts', + customFontLookup: + (String fontFamily, String fontStyle, String fontWeight) { + switch (fontFamily) { + case customFamilyName1: + return customFont1; + case customFamilyName2: + return customFont2; + default: + return null; + } + }), ), ); });