Showing
9 changed files
with
96 additions
and
54 deletions
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | * Implement drawShape | 8 | * Implement drawShape |
9 | * Add support for Jpeg images | 9 | * Add support for Jpeg images |
10 | * Fix numeric conversions in graphic operations | 10 | * Fix numeric conversions in graphic operations |
11 | +* Add unicode support for annotations and info block | ||
11 | 12 | ||
12 | # 1.0.8 | 13 | # 1.0.8 |
13 | * Fix monospace TTF font loading | 14 | * Fix monospace TTF font loading |
@@ -22,6 +22,7 @@ import 'dart:convert'; | @@ -22,6 +22,7 @@ import 'dart:convert'; | ||
22 | import 'dart:typed_data'; | 22 | import 'dart:typed_data'; |
23 | 23 | ||
24 | import 'package:meta/meta.dart'; | 24 | import 'package:meta/meta.dart'; |
25 | +import 'package:utf/utf.dart'; | ||
25 | import 'package:vector_math/vector_math_64.dart'; | 26 | import 'package:vector_math/vector_math_64.dart'; |
26 | 27 | ||
27 | part 'src/annotation.dart'; | 28 | part 'src/annotation.dart'; |
@@ -97,7 +97,7 @@ class PdfAnnot extends PdfObject { | @@ -97,7 +97,7 @@ class PdfAnnot extends PdfObject { | ||
97 | 97 | ||
98 | // Now the annotation subtypes | 98 | // Now the annotation subtypes |
99 | if (subtype == "/Text") { | 99 | if (subtype == "/Text") { |
100 | - params["/Contents"] = PdfStream.text(content); | 100 | + params["/Contents"] = PdfStream()..putLiteral(content); |
101 | } else if (subtype == "/Link") { | 101 | } else if (subtype == "/Link") { |
102 | var dests = List<PdfStream>(); | 102 | var dests = List<PdfStream>(); |
103 | dests.add(dest.ref()); | 103 | dests.add(dest.ref()); |
@@ -96,7 +96,6 @@ class PdfDocument { | @@ -96,7 +96,6 @@ class PdfDocument { | ||
96 | // Now create some standard objects | 96 | // Now create some standard objects |
97 | pdfPageList = PdfPageList(this); | 97 | pdfPageList = PdfPageList(this); |
98 | catalog = PdfCatalog(this, pdfPageList, pageMode); | 98 | catalog = PdfCatalog(this, pdfPageList, pageMode); |
99 | - info = PdfInfo(this); | ||
100 | } | 99 | } |
101 | 100 | ||
102 | /// This returns a specific page. It's used mainly when using a | 101 | /// This returns a specific page. It's used mainly when using a |
@@ -19,28 +19,43 @@ | @@ -19,28 +19,43 @@ | ||
19 | part of pdf; | 19 | part of pdf; |
20 | 20 | ||
21 | class PdfInfo extends PdfObject { | 21 | class PdfInfo extends PdfObject { |
22 | - String author; | ||
23 | - String creator; | ||
24 | - String title; | ||
25 | - String subject; | ||
26 | - String keywords; | 22 | + static const String _libraryName = "https://github.com/DavBfr/dart_pdf"; |
23 | + final String author; | ||
24 | + final String creator; | ||
25 | + final String title; | ||
26 | + final String subject; | ||
27 | + final String keywords; | ||
28 | + final String producer; | ||
27 | 29 | ||
28 | /// @param title Title of this document | 30 | /// @param title Title of this document |
29 | PdfInfo(PdfDocument pdfDocument, | 31 | PdfInfo(PdfDocument pdfDocument, |
30 | - {this.title, this.author, this.creator, this.subject, this.keywords}) | 32 | + {this.title, |
33 | + this.author, | ||
34 | + this.creator, | ||
35 | + this.subject, | ||
36 | + this.keywords, | ||
37 | + this.producer}) | ||
31 | : super(pdfDocument, null) { | 38 | : super(pdfDocument, null) { |
32 | - params["/Producer"] = PdfStream.text("dpdf - David PHAM-VAN"); | 39 | + if (author != null) { |
40 | + params["/Author"] = PdfStream()..putLiteral(author); | ||
41 | + } | ||
42 | + if (creator != null) { | ||
43 | + params["/Creator"] = PdfStream()..putLiteral(creator); | ||
44 | + } | ||
45 | + if (title != null) { | ||
46 | + params["/Title"] = PdfStream()..putLiteral(title); | ||
47 | + } | ||
48 | + if (subject != null) { | ||
49 | + params["/Subject"] = PdfStream()..putLiteral(subject); | ||
50 | + } | ||
51 | + if (keywords != null) { | ||
52 | + params["/Keywords"] = PdfStream()..putLiteral(keywords); | ||
53 | + } | ||
54 | + if (producer != null) { | ||
55 | + params["/Producer"] = PdfStream() | ||
56 | + ..putLiteral("$producer ($_libraryName)"); | ||
57 | + } else { | ||
58 | + params["/Producer"] = PdfStream()..putLiteral(_libraryName); | ||
33 | } | 59 | } |
34 | - | ||
35 | - /// @param os OutputStream to send the object to | ||
36 | - @override | ||
37 | - void _prepare() { | ||
38 | - super._prepare(); | ||
39 | - | ||
40 | - if (author != null) params["/Author"] = PdfStream.text(author); | ||
41 | - if (creator != null) params["/Creator"] = PdfStream.text(creator); | ||
42 | - if (title != null) params["/Title"] = PdfStream.text(title); | ||
43 | - if (subject != null) params["/Subject"] = PdfStream.text(subject); | ||
44 | - if (keywords != null) params["/Keywords"] = PdfStream.text(keywords); | ||
45 | } | 60 | } |
46 | } | 61 | } |
@@ -60,31 +60,61 @@ class PdfStream { | @@ -60,31 +60,61 @@ class PdfStream { | ||
60 | static PdfStream num(double d) => PdfStream()..putNum(d); | 60 | static PdfStream num(double d) => PdfStream()..putNum(d); |
61 | static PdfStream intNum(int i) => PdfStream()..putString(i.toString()); | 61 | static PdfStream intNum(int i) => PdfStream()..putString(i.toString()); |
62 | 62 | ||
63 | + /// Escape special characters | ||
64 | + /// \ddd Character code ddd (octal) | ||
65 | + void putTextBytes(List<int> s) { | ||
66 | + for (var c in s) { | ||
67 | + switch (c) { | ||
68 | + case 0x0a: // \n Line feed (LF) | ||
69 | + _stream.add(0x5c); | ||
70 | + _stream.add(0x6e); | ||
71 | + break; | ||
72 | + case 0x0d: // \r Carriage return (CR) | ||
73 | + _stream.add(0x5c); | ||
74 | + _stream.add(0x72); | ||
75 | + break; | ||
76 | + case 0x09: // \t Horizontal tab (HT) | ||
77 | + _stream.add(0x5c); | ||
78 | + _stream.add(0x74); | ||
79 | + break; | ||
80 | + case 0x08: // \b Backspace (BS) | ||
81 | + _stream.add(0x5c); | ||
82 | + _stream.add(0x62); | ||
83 | + break; | ||
84 | + case 0x0c: // \f Form feed (FF) | ||
85 | + _stream.add(0x5c); | ||
86 | + _stream.add(0x66); | ||
87 | + break; | ||
88 | + case 0x28: // \( Left parenthesis | ||
89 | + _stream.add(0x5c); | ||
90 | + _stream.add(0x28); | ||
91 | + break; | ||
92 | + case 0x29: // \) Right parenthesis | ||
93 | + _stream.add(0x5c); | ||
94 | + _stream.add(0x29); | ||
95 | + break; | ||
96 | + case 0x5c: // \\ Backslash | ||
97 | + _stream.add(0x5c); | ||
98 | + _stream.add(0x5c); | ||
99 | + break; | ||
100 | + default: | ||
101 | + _stream.add(c); | ||
102 | + } | ||
103 | + } | ||
104 | + } | ||
105 | + | ||
63 | void putText(String s) { | 106 | void putText(String s) { |
64 | - // Escape special characters | ||
65 | - // \n Line feed (LF) | ||
66 | - // \r Carriage return (CR) | ||
67 | - // \t Horizontal tab (HT) | ||
68 | - // \b Backspace (BS) | ||
69 | - // \f Form feed (FF) | ||
70 | - // \( Left parenthesis | ||
71 | - // \) Right parenthesis | ||
72 | - // \\ Backslash | ||
73 | - // \ddd Character code ddd (octal) | ||
74 | - s = s | ||
75 | - .replaceAll('\\', '\\\\') | ||
76 | - .replaceAll('(', '\\(') | ||
77 | - .replaceAll(')', '\\)') | ||
78 | - .replaceAll('\n', '\\n') | ||
79 | - .replaceAll('\t', '\\t') | ||
80 | - .replaceAll('\b', '\\b') | ||
81 | - .replaceAll('\f', '\\f') | ||
82 | - .replaceAll('\r', '\\r'); | ||
83 | - | ||
84 | - putBytes(latin1.encode('(' + s + ')')); | ||
85 | - } | ||
86 | - | ||
87 | - static PdfStream text(String s) => PdfStream()..putText(s); | 107 | + putBytes(latin1.encode('(')); |
108 | + putTextBytes(latin1.encode(s)); | ||
109 | + putBytes(latin1.encode(')')); | ||
110 | + } | ||
111 | + | ||
112 | + void putLiteral(String s) { | ||
113 | + putBytes(latin1.encode('(')); | ||
114 | + putBytes([0xfe, 0xff]); | ||
115 | + putTextBytes(encodeUtf16be(s)); | ||
116 | + putBytes(latin1.encode(')')); | ||
117 | + } | ||
88 | 118 | ||
89 | void putBool(bool value) { | 119 | void putBool(bool value) { |
90 | putString(value ? "true" : "false"); | 120 | putString(value ? "true" : "false"); |
@@ -12,11 +12,11 @@ void main() { | @@ -12,11 +12,11 @@ void main() { | ||
12 | img.fillRange(0, img.length - 1, 0x12345678); | 12 | img.fillRange(0, img.length - 1, 0x12345678); |
13 | 13 | ||
14 | var pdf = PdfDocument(deflate: zlib.encode); | 14 | var pdf = PdfDocument(deflate: zlib.encode); |
15 | - var i = pdf.info; | ||
16 | - i.author = "David PHAM-VAN"; | ||
17 | - i.creator = i.author; | ||
18 | - i.title = "My Title"; | ||
19 | - i.subject = "My Subject"; | 15 | + pdf.info = PdfInfo(pdf, |
16 | + author: "David PHAM-VAN", | ||
17 | + creator: "David PHAM-VAN", | ||
18 | + title: "My Title", | ||
19 | + subject: "My Subject"); | ||
20 | var page = PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0)); | 20 | var page = PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0)); |
21 | 21 | ||
22 | var g = page.getGraphics(); | 22 | var g = page.getGraphics(); |
@@ -7,11 +7,6 @@ import 'package:test/test.dart'; | @@ -7,11 +7,6 @@ import 'package:test/test.dart'; | ||
7 | void main() { | 7 | void main() { |
8 | test('Pdf', () { | 8 | test('Pdf', () { |
9 | var pdf = PdfDocument(); | 9 | var pdf = PdfDocument(); |
10 | - var i = pdf.info; | ||
11 | - i.author = "David PHAM-VAN"; | ||
12 | - i.creator = i.author; | ||
13 | - i.title = "My Title"; | ||
14 | - i.subject = "My Subject"; | ||
15 | var page = PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0)); | 10 | var page = PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0)); |
16 | 11 | ||
17 | var g = page.getGraphics(); | 12 | var g = page.getGraphics(); |
-
Please register or login to post a comment