David PHAM-VAN

Add unicode support for annotations and info block

@@ -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");  
33 - }  
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); 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);
  59 + }
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 + ')')); 107 + putBytes(latin1.encode('('));
  108 + putTextBytes(latin1.encode(s));
  109 + putBytes(latin1.encode(')'));
85 } 110 }
86 111
87 - static PdfStream text(String s) => PdfStream()..putText(s); 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");
@@ -10,6 +10,7 @@ environment: @@ -10,6 +10,7 @@ environment:
10 dependencies: 10 dependencies:
11 meta: "^1.1.5" 11 meta: "^1.1.5"
12 vector_math: "^2.0.0" 12 vector_math: "^2.0.0"
  13 + utf: "^0.9.0"
13 14
14 dev_dependencies: 15 dev_dependencies:
15 test: any 16 test: any
@@ -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();