Showing
4 changed files
with
51 additions
and
5 deletions
@@ -18,7 +18,6 @@ import 'dart:convert'; | @@ -18,7 +18,6 @@ import 'dart:convert'; | ||
18 | import 'dart:typed_data'; | 18 | import 'dart:typed_data'; |
19 | 19 | ||
20 | import 'package:meta/meta.dart'; | 20 | import 'package:meta/meta.dart'; |
21 | -import 'package:utf/utf.dart'; | ||
22 | 21 | ||
23 | import 'color.dart'; | 22 | import 'color.dart'; |
24 | import 'object.dart'; | 23 | import 'object.dart'; |
@@ -120,7 +119,7 @@ class PdfString extends PdfDataType { | @@ -120,7 +119,7 @@ class PdfString extends PdfDataType { | ||
120 | try { | 119 | try { |
121 | return latin1.encode(value); | 120 | return latin1.encode(value); |
122 | } catch (e) { | 121 | } catch (e) { |
123 | - return Uint8List.fromList(<int>[0xfe, 0xff] + encodeUtf16be(value)); | 122 | + return Uint8List.fromList(<int>[0xfe, 0xff] + _encodeUtf16be(value)); |
124 | } | 123 | } |
125 | } | 124 | } |
126 | 125 | ||
@@ -135,6 +134,46 @@ class PdfString extends PdfDataType { | @@ -135,6 +134,46 @@ class PdfString extends PdfDataType { | ||
135 | return _string('D:$year$month$day$hour$minute${second}Z'); | 134 | return _string('D:$year$month$day$hour$minute${second}Z'); |
136 | } | 135 | } |
137 | 136 | ||
137 | + /// Produce a list of UTF-16BE encoded bytes. | ||
138 | + static List<int> _encodeUtf16be(String str) { | ||
139 | + const UNICODE_REPLACEMENT_CHARACTER_CODEPOINT = 0xfffd; | ||
140 | + const UNICODE_BYTE_ZERO_MASK = 0xff; | ||
141 | + const UNICODE_BYTE_ONE_MASK = 0xff00; | ||
142 | + const UNICODE_VALID_RANGE_MAX = 0x10ffff; | ||
143 | + const UNICODE_PLANE_ONE_MAX = 0xffff; | ||
144 | + const UNICODE_UTF16_RESERVED_LO = 0xd800; | ||
145 | + const UNICODE_UTF16_RESERVED_HI = 0xdfff; | ||
146 | + const UNICODE_UTF16_OFFSET = 0x10000; | ||
147 | + const UNICODE_UTF16_SURROGATE_UNIT_0_BASE = 0xd800; | ||
148 | + const UNICODE_UTF16_SURROGATE_UNIT_1_BASE = 0xdc00; | ||
149 | + const UNICODE_UTF16_HI_MASK = 0xffc00; | ||
150 | + const UNICODE_UTF16_LO_MASK = 0x3ff; | ||
151 | + | ||
152 | + final encoding = <int>[]; | ||
153 | + | ||
154 | + final add = (int unit) { | ||
155 | + encoding.add((unit & UNICODE_BYTE_ONE_MASK) >> 8); | ||
156 | + encoding.add(unit & UNICODE_BYTE_ZERO_MASK); | ||
157 | + }; | ||
158 | + | ||
159 | + for (var unit in str.codeUnits) { | ||
160 | + if ((unit >= 0 && unit < UNICODE_UTF16_RESERVED_LO) || | ||
161 | + (unit > UNICODE_UTF16_RESERVED_HI && unit <= UNICODE_PLANE_ONE_MAX)) { | ||
162 | + add(unit); | ||
163 | + } else if (unit > UNICODE_PLANE_ONE_MAX && | ||
164 | + unit <= UNICODE_VALID_RANGE_MAX) { | ||
165 | + final base = unit - UNICODE_UTF16_OFFSET; | ||
166 | + add(UNICODE_UTF16_SURROGATE_UNIT_0_BASE + | ||
167 | + ((base & UNICODE_UTF16_HI_MASK) >> 10)); | ||
168 | + add(UNICODE_UTF16_SURROGATE_UNIT_1_BASE + | ||
169 | + (base & UNICODE_UTF16_LO_MASK)); | ||
170 | + } else { | ||
171 | + add(UNICODE_REPLACEMENT_CHARACTER_CODEPOINT); | ||
172 | + } | ||
173 | + } | ||
174 | + return encoding; | ||
175 | + } | ||
176 | + | ||
138 | /// Escape special characters | 177 | /// Escape special characters |
139 | /// \ddd Character code ddd (octal) | 178 | /// \ddd Character code ddd (octal) |
140 | void _putTextBytes(PdfStream s, List<int> b) { | 179 | void _putTextBytes(PdfStream s, List<int> b) { |
@@ -19,7 +19,6 @@ import 'dart:math' as math; | @@ -19,7 +19,6 @@ import 'dart:math' as math; | ||
19 | import 'dart:typed_data'; | 19 | import 'dart:typed_data'; |
20 | 20 | ||
21 | import 'package:meta/meta.dart'; | 21 | import 'package:meta/meta.dart'; |
22 | -import 'package:utf/utf.dart'; | ||
23 | 22 | ||
24 | import 'font_metrics.dart'; | 23 | import 'font_metrics.dart'; |
25 | 24 | ||
@@ -125,7 +124,7 @@ class TtfParser { | @@ -125,7 +124,7 @@ class TtfParser { | ||
125 | } | 124 | } |
126 | if (platformID == 3 && nameID == 6) { | 125 | if (platformID == 3 && nameID == 6) { |
127 | try { | 126 | try { |
128 | - _fontName = decodeUtf16(bytes.buffer | 127 | + _fontName = _decodeUtf16(bytes.buffer |
129 | .asUint8List(basePosition + stringOffset + offset, length)); | 128 | .asUint8List(basePosition + stringOffset + offset, length)); |
130 | return; | 129 | return; |
131 | } catch (a) { | 130 | } catch (a) { |
@@ -403,4 +402,12 @@ class TtfParser { | @@ -403,4 +402,12 @@ class TtfParser { | ||
403 | components, | 402 | components, |
404 | ); | 403 | ); |
405 | } | 404 | } |
405 | + | ||
406 | + String _decodeUtf16(Uint8List bytes) { | ||
407 | + final charCodes = <int>[]; | ||
408 | + for (var i = 0; i < bytes.length; i += 2) { | ||
409 | + charCodes.add((bytes[i] << 8) | bytes[i + 1]); | ||
410 | + } | ||
411 | + return String.fromCharCodes(charCodes); | ||
412 | + } | ||
406 | } | 413 | } |
-
Please register or login to post a comment