Showing
9 changed files
with
95 additions
and
53 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"); | ||
| 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"); |
| @@ -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