Showing
3 changed files
with
71 additions
and
35 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,45 +60,79 @@ class PdfTtfFont extends PdfFont { | @@ -57,45 +60,79 @@ 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(); | 112 | + params['/Encoding'] = PdfStream.string('/Identity-H'); |
| 113 | + params['/DescendantFonts'] = PdfStream() | ||
| 114 | + ..putArray(<PdfStream>[descendantFont]); | ||
| 115 | + params['/ToUnicode'] = unicodeCMap.ref(); | ||
| 116 | + | ||
| 117 | + charMin = 0; | ||
| 118 | + charMax = unicodeCMap.cmap.length - 1; | ||
| 119 | + for (int i = charMin; i <= charMax; i++) { | ||
| 120 | + widthsObject.values.add( | ||
| 121 | + (glyphMetrics(unicodeCMap.cmap[i]).advanceWidth * 1000.0) | ||
| 122 | + .toInt() | ||
| 123 | + .toString()); | ||
| 124 | + } | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + @override | ||
| 128 | + void _prepare() { | ||
| 129 | + super._prepare(); | ||
| 130 | + | ||
| 75 | if (font.unicode) { | 131 | if (font.unicode) { |
| 76 | - if (params.containsKey('/Encoding')) { | ||
| 77 | - params.remove('/Encoding'); | ||
| 78 | - } | ||
| 79 | - params['/ToUnicode'] = unicodeCMap.ref(); | ||
| 80 | - charMin = 0; | ||
| 81 | - charMax = unicodeCMap.cmap.length - 1; | ||
| 82 | - for (int i = charMin; i <= charMax; i++) { | ||
| 83 | - widthsObject.values.add( | ||
| 84 | - (glyphMetrics(unicodeCMap.cmap[i]).advanceWidth * 1000.0) | ||
| 85 | - .toInt() | ||
| 86 | - .toString()); | ||
| 87 | - } | 132 | + _buildType0(params); |
| 88 | } else { | 133 | } 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 | - } | 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