Showing
3 changed files
with
63 additions
and
27 deletions
@@ -27,6 +27,9 @@ class PdfTtfFont extends PdfFont { | @@ -27,6 +27,9 @@ class PdfTtfFont extends PdfFont { | ||
27 | widthsObject = PdfArrayObject(pdfDocument, <String>[]); | 27 | widthsObject = PdfArrayObject(pdfDocument, <String>[]); |
28 | } | 28 | } |
29 | 29 | ||
30 | + @override | ||
31 | + String get subtype => font.unicode ? '/Type0' : super.subtype; | ||
32 | + | ||
30 | PdfUnicodeCmap unicodeCMap; | 33 | PdfUnicodeCmap unicodeCMap; |
31 | 34 | ||
32 | PdfFontDescriptor descriptor; | 35 | PdfFontDescriptor descriptor; |
@@ -57,26 +60,60 @@ class PdfTtfFont extends PdfFont { | @@ -57,26 +60,60 @@ class PdfTtfFont extends PdfFont { | ||
57 | return font.glyphInfoMap[g] ?? PdfFontMetrics.zero; | 60 | return font.glyphInfoMap[g] ?? PdfFontMetrics.zero; |
58 | } | 61 | } |
59 | 62 | ||
60 | - @override | ||
61 | - void _prepare() { | 63 | + void _buildTrueType(Map<String, PdfStream> params) { |
62 | int charMin; | 64 | int charMin; |
63 | int charMax; | 65 | int charMax; |
64 | 66 | ||
65 | - super._prepare(); | 67 | + file.buf.putBytes(font.bytes.buffer.asUint8List()); |
68 | + file.params['/Length1'] = PdfStream.intNum(font.bytes.lengthInBytes); | ||
69 | + | ||
70 | + params['/BaseFont'] = PdfStream.string('/' + fontName); | ||
71 | + params['/FontDescriptor'] = descriptor.ref(); | ||
72 | + charMin = 32; | ||
73 | + charMax = 255; | ||
74 | + for (int i = charMin; i <= charMax; i++) { | ||
75 | + widthsObject.values | ||
76 | + .add((glyphMetrics(i).advanceWidth * 1000.0).toInt().toString()); | ||
77 | + } | ||
78 | + params['/FirstChar'] = PdfStream.intNum(charMin); | ||
79 | + params['/LastChar'] = PdfStream.intNum(charMax); | ||
80 | + params['/Widths'] = widthsObject.ref(); | ||
81 | + } | ||
82 | + | ||
83 | + void _buildType0(Map<String, PdfStream> params) { | ||
84 | + int charMin; | ||
85 | + int charMax; | ||
66 | 86 | ||
67 | final TtfWriter ttfWriter = TtfWriter(font); | 87 | final TtfWriter ttfWriter = TtfWriter(font); |
68 | final Uint8List data = ttfWriter.withChars(unicodeCMap.cmap); | 88 | final Uint8List data = ttfWriter.withChars(unicodeCMap.cmap); |
69 | - | ||
70 | file.buf.putBytes(data); | 89 | file.buf.putBytes(data); |
71 | file.params['/Length1'] = PdfStream.intNum(data.length); | 90 | file.params['/Length1'] = PdfStream.intNum(data.length); |
72 | 91 | ||
92 | + final PdfStream descendantFont = PdfStream.dictionary(<String, PdfStream>{ | ||
93 | + '/Type': PdfStream.string('/Font'), | ||
94 | + '/BaseFont': PdfStream.string('/' + fontName), | ||
95 | + '/FontFile2': file.ref(), | ||
96 | + '/FontDescriptor': descriptor.ref(), | ||
97 | + '/W': PdfStream.array(<PdfStream>[ | ||
98 | + PdfStream.intNum(0), | ||
99 | + widthsObject.ref(), | ||
100 | + ]), | ||
101 | + '/CIDToGIDMap': PdfStream.string('/Identity'), | ||
102 | + '/DW': PdfStream.string('1000'), | ||
103 | + '/Subtype': PdfStream.string('/CIDFontType2'), | ||
104 | + '/CIDSystemInfo': PdfStream.dictionary(<String, PdfStream>{ | ||
105 | + '/Supplement': PdfStream.intNum(0), | ||
106 | + '/Registry': PdfStream()..putText('Adobe'), | ||
107 | + '/Ordering': PdfStream()..putText('Identity-H'), | ||
108 | + }) | ||
109 | + }); | ||
110 | + | ||
73 | params['/BaseFont'] = PdfStream.string('/' + fontName); | 111 | params['/BaseFont'] = PdfStream.string('/' + fontName); |
74 | - params['/FontDescriptor'] = descriptor.ref(); | ||
75 | - if (font.unicode) { | ||
76 | - if (params.containsKey('/Encoding')) { | ||
77 | - params.remove('/Encoding'); | ||
78 | - } | 112 | + params['/Encoding'] = PdfStream.string('/Identity-H'); |
113 | + params['/DescendantFonts'] = PdfStream() | ||
114 | + ..putArray(<PdfStream>[descendantFont]); | ||
79 | params['/ToUnicode'] = unicodeCMap.ref(); | 115 | params['/ToUnicode'] = unicodeCMap.ref(); |
116 | + | ||
80 | charMin = 0; | 117 | charMin = 0; |
81 | charMax = unicodeCMap.cmap.length - 1; | 118 | charMax = unicodeCMap.cmap.length - 1; |
82 | for (int i = charMin; i <= charMax; i++) { | 119 | for (int i = charMin; i <= charMax; i++) { |
@@ -85,17 +122,17 @@ class PdfTtfFont extends PdfFont { | @@ -85,17 +122,17 @@ class PdfTtfFont extends PdfFont { | ||
85 | .toInt() | 122 | .toInt() |
86 | .toString()); | 123 | .toString()); |
87 | } | 124 | } |
88 | - } else { | ||
89 | - charMin = 32; | ||
90 | - charMax = 255; | ||
91 | - for (int i = charMin; i <= charMax; i++) { | ||
92 | - widthsObject.values | ||
93 | - .add((glyphMetrics(i).advanceWidth * 1000.0).toInt().toString()); | ||
94 | } | 125 | } |
126 | + | ||
127 | + @override | ||
128 | + void _prepare() { | ||
129 | + super._prepare(); | ||
130 | + | ||
131 | + if (font.unicode) { | ||
132 | + _buildType0(params); | ||
133 | + } else { | ||
134 | + _buildTrueType(params); | ||
95 | } | 135 | } |
96 | - params['/FirstChar'] = PdfStream.intNum(charMin); | ||
97 | - params['/LastChar'] = PdfStream.intNum(charMax); | ||
98 | - params['/Widths'] = widthsObject.ref(); | ||
99 | } | 136 | } |
100 | 137 | ||
101 | @override | 138 | @override |
@@ -105,7 +142,8 @@ class PdfTtfFont extends PdfFont { | @@ -105,7 +142,8 @@ class PdfTtfFont extends PdfFont { | ||
105 | } | 142 | } |
106 | 143 | ||
107 | final Runes runes = text.runes; | 144 | final Runes runes = text.runes; |
108 | - final List<int> bytes = List<int>(); | 145 | + final PdfStream stream = PdfStream(); |
146 | + stream.putBytes(latin1.encode('<')); | ||
109 | for (int rune in runes) { | 147 | for (int rune in runes) { |
110 | int char = unicodeCMap.cmap.indexOf(rune); | 148 | int char = unicodeCMap.cmap.indexOf(rune); |
111 | if (char == -1) { | 149 | if (char == -1) { |
@@ -113,13 +151,10 @@ class PdfTtfFont extends PdfFont { | @@ -113,13 +151,10 @@ class PdfTtfFont extends PdfFont { | ||
113 | unicodeCMap.cmap.add(rune); | 151 | unicodeCMap.cmap.add(rune); |
114 | } | 152 | } |
115 | 153 | ||
116 | - bytes.add(char); | 154 | + stream.putBytes(latin1.encode(char.toRadixString(16).padLeft(4, '0'))); |
117 | } | 155 | } |
118 | - | ||
119 | - return PdfStream() | ||
120 | - ..putBytes(latin1.encode('(')) | ||
121 | - ..putTextBytes(bytes) | ||
122 | - ..putBytes(latin1.encode(')')); | 156 | + stream.putBytes(latin1.encode('>')); |
157 | + return stream; | ||
123 | } | 158 | } |
124 | 159 | ||
125 | @override | 160 | @override |
@@ -34,14 +34,14 @@ class PdfUnicodeCmap extends PdfObjectStream { | @@ -34,14 +34,14 @@ class PdfUnicodeCmap extends PdfObjectStream { | ||
34 | '/CMapName/Adobe-Identity-UCS def\n' | 34 | '/CMapName/Adobe-Identity-UCS def\n' |
35 | '/CMapType 2 def\n' | 35 | '/CMapType 2 def\n' |
36 | '1 begincodespacerange\n' | 36 | '1 begincodespacerange\n' |
37 | - '<00> <FF>\n' | 37 | + '<0000> <FFFF>\n' |
38 | 'endcodespacerange\n' | 38 | 'endcodespacerange\n' |
39 | '${cmap.length} beginbfchar\n'); | 39 | '${cmap.length} beginbfchar\n'); |
40 | 40 | ||
41 | for (int key = 0; key < cmap.length; key++) { | 41 | for (int key = 0; key < cmap.length; key++) { |
42 | final int value = cmap[key]; | 42 | final int value = cmap[key]; |
43 | buf.putString('<' + | 43 | buf.putString('<' + |
44 | - key.toRadixString(16).toUpperCase().padLeft(2, '0') + | 44 | + key.toRadixString(16).toUpperCase().padLeft(4, '0') + |
45 | '> <' + | 45 | '> <' + |
46 | value.toRadixString(16).toUpperCase().padLeft(4, '0') + | 46 | value.toRadixString(16).toUpperCase().padLeft(4, '0') + |
47 | '>\n'); | 47 | '>\n'); |
-
Please register or login to post a comment