Showing
5 changed files
with
56 additions
and
14 deletions
| @@ -22,6 +22,32 @@ import 'package:meta/meta.dart'; | @@ -22,6 +22,32 @@ import 'package:meta/meta.dart'; | ||
| 22 | 22 | ||
| 23 | import 'font_metrics.dart'; | 23 | import 'font_metrics.dart'; |
| 24 | 24 | ||
| 25 | +enum TtfParserName { | ||
| 26 | + copyright, | ||
| 27 | + fontFamily, | ||
| 28 | + fontSubfamily, | ||
| 29 | + uniqueID, | ||
| 30 | + fullName, | ||
| 31 | + version, | ||
| 32 | + postScriptName, | ||
| 33 | + trademark, | ||
| 34 | + manufacturer, | ||
| 35 | + designer, | ||
| 36 | + description, | ||
| 37 | + manufacturerURL, | ||
| 38 | + designerURL, | ||
| 39 | + license, | ||
| 40 | + licenseURL, | ||
| 41 | + reserved, | ||
| 42 | + preferredFamily, | ||
| 43 | + preferredSubfamily, | ||
| 44 | + compatibleFullName, | ||
| 45 | + sampleText, | ||
| 46 | + postScriptFindFontName, | ||
| 47 | + wwsFamily, | ||
| 48 | + wwsSubfamily, | ||
| 49 | +} | ||
| 50 | + | ||
| 25 | @immutable | 51 | @immutable |
| 26 | class TtfGlyphInfo { | 52 | class TtfGlyphInfo { |
| 27 | const TtfGlyphInfo(this.index, this.data, this.compounds); | 53 | const TtfGlyphInfo(this.index, this.data, this.compounds); |
| @@ -71,7 +97,6 @@ class TtfParser { | @@ -71,7 +97,6 @@ class TtfParser { | ||
| 71 | assert(tableOffsets.containsKey(glyf_table), | 97 | assert(tableOffsets.containsKey(glyf_table), |
| 72 | 'Unable to find the `glyf` table. This file is not a supported TTF font'); | 98 | 'Unable to find the `glyf` table. This file is not a supported TTF font'); |
| 73 | 99 | ||
| 74 | - _parseFontName(); | ||
| 75 | _parseCMap(); | 100 | _parseCMap(); |
| 76 | _parseIndexes(); | 101 | _parseIndexes(); |
| 77 | _parseGlyphs(); | 102 | _parseGlyphs(); |
| @@ -89,7 +114,7 @@ class TtfParser { | @@ -89,7 +114,7 @@ class TtfParser { | ||
| 89 | final UnmodifiableByteDataView bytes; | 114 | final UnmodifiableByteDataView bytes; |
| 90 | final Map<String, int> tableOffsets = <String, int>{}; | 115 | final Map<String, int> tableOffsets = <String, int>{}; |
| 91 | final Map<String, int> tableSize = <String, int>{}; | 116 | final Map<String, int> tableSize = <String, int>{}; |
| 92 | - String? _fontName; | 117 | + |
| 93 | final Map<int, int> charToGlyphIndexMap = <int, int>{}; | 118 | final Map<int, int> charToGlyphIndexMap = <int, int>{}; |
| 94 | final List<int> glyphOffsets = <int>[]; | 119 | final List<int> glyphOffsets = <int>[]; |
| 95 | final Map<int, PdfFontMetrics> glyphInfoMap = <int, PdfFontMetrics>{}; | 120 | final Map<int, PdfFontMetrics> glyphInfoMap = <int, PdfFontMetrics>{}; |
| @@ -115,42 +140,46 @@ class TtfParser { | @@ -115,42 +140,46 @@ class TtfParser { | ||
| 115 | 140 | ||
| 116 | int get numGlyphs => bytes.getUint16(tableOffsets[maxp_table]! + 4); | 141 | int get numGlyphs => bytes.getUint16(tableOffsets[maxp_table]! + 4); |
| 117 | 142 | ||
| 118 | - String? get fontName => _fontName; | 143 | + String get fontName => |
| 144 | + getNameID(TtfParserName.postScriptName) ?? hashCode.toString(); | ||
| 119 | 145 | ||
| 120 | bool get unicode => bytes.getUint32(0) == 0x10000; | 146 | bool get unicode => bytes.getUint32(0) == 0x10000; |
| 121 | 147 | ||
| 122 | // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html | 148 | // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html |
| 123 | - void _parseFontName() { | 149 | + String? getNameID(TtfParserName fontNameID) { |
| 124 | final basePosition = tableOffsets[name_table]!; | 150 | final basePosition = tableOffsets[name_table]!; |
| 151 | + // final format = bytes.getUint16(basePosition); | ||
| 125 | final count = bytes.getUint16(basePosition + 2); | 152 | final count = bytes.getUint16(basePosition + 2); |
| 126 | final stringOffset = bytes.getUint16(basePosition + 4); | 153 | final stringOffset = bytes.getUint16(basePosition + 4); |
| 127 | var pos = basePosition + 6; | 154 | var pos = basePosition + 6; |
| 155 | + String? _fontName; | ||
| 156 | + | ||
| 128 | for (var i = 0; i < count; i++) { | 157 | for (var i = 0; i < count; i++) { |
| 129 | final platformID = bytes.getUint16(pos); | 158 | final platformID = bytes.getUint16(pos); |
| 130 | final nameID = bytes.getUint16(pos + 6); | 159 | final nameID = bytes.getUint16(pos + 6); |
| 131 | final length = bytes.getUint16(pos + 8); | 160 | final length = bytes.getUint16(pos + 8); |
| 132 | final offset = bytes.getUint16(pos + 10); | 161 | final offset = bytes.getUint16(pos + 10); |
| 133 | pos += 12; | 162 | pos += 12; |
| 134 | - if (platformID == 1 && nameID == 6) { | 163 | + |
| 164 | + if (platformID == 1 && nameID == fontNameID.index) { | ||
| 135 | try { | 165 | try { |
| 136 | _fontName = utf8.decode(bytes.buffer | 166 | _fontName = utf8.decode(bytes.buffer |
| 137 | .asUint8List(basePosition + stringOffset + offset, length)); | 167 | .asUint8List(basePosition + stringOffset + offset, length)); |
| 138 | - return; | ||
| 139 | } catch (a) { | 168 | } catch (a) { |
| 140 | print('Error: $platformID $nameID $a'); | 169 | print('Error: $platformID $nameID $a'); |
| 141 | } | 170 | } |
| 142 | } | 171 | } |
| 143 | - if (platformID == 3 && nameID == 6) { | 172 | + |
| 173 | + if (platformID == 3 && nameID == fontNameID.index) { | ||
| 144 | try { | 174 | try { |
| 145 | - _fontName = _decodeUtf16(bytes.buffer | 175 | + return _decodeUtf16(bytes.buffer |
| 146 | .asUint8List(basePosition + stringOffset + offset, length)); | 176 | .asUint8List(basePosition + stringOffset + offset, length)); |
| 147 | - return; | ||
| 148 | } catch (a) { | 177 | } catch (a) { |
| 149 | print('Error: $platformID $nameID $a'); | 178 | print('Error: $platformID $nameID $a'); |
| 150 | } | 179 | } |
| 151 | } | 180 | } |
| 152 | } | 181 | } |
| 153 | - _fontName = hashCode.toString(); | 182 | + return _fontName; |
| 154 | } | 183 | } |
| 155 | 184 | ||
| 156 | void _parseCMap() { | 185 | void _parseCMap() { |
| @@ -55,7 +55,7 @@ class PdfTtfFont extends PdfFont { | @@ -55,7 +55,7 @@ class PdfTtfFont extends PdfFont { | ||
| 55 | final TtfParser font; | 55 | final TtfParser font; |
| 56 | 56 | ||
| 57 | @override | 57 | @override |
| 58 | - String get fontName => font.fontName!; | 58 | + String get fontName => font.fontName; |
| 59 | 59 | ||
| 60 | @override | 60 | @override |
| 61 | double get ascent => font.ascent.toDouble() / font.unitsPerEm; | 61 | double get ascent => font.ascent.toDouble() / font.unitsPerEm; |
| @@ -82,7 +82,7 @@ class Font { | @@ -82,7 +82,7 @@ class Font { | ||
| 82 | Type1Fonts.zapfDingbats: 'ZapfDingbats' | 82 | Type1Fonts.zapfDingbats: 'ZapfDingbats' |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | - String? get fontName => _type1Map[font]; | 85 | + String get fontName => _type1Map[font]!; |
| 86 | 86 | ||
| 87 | @protected | 87 | @protected |
| 88 | PdfFont buildFont(PdfDocument pdfDocument) { | 88 | PdfFont buildFont(PdfDocument pdfDocument) { |
| @@ -153,7 +153,7 @@ class TtfFont extends Font { | @@ -153,7 +153,7 @@ class TtfFont extends Font { | ||
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | @override | 155 | @override |
| 156 | - String? get fontName { | 156 | + String get fontName { |
| 157 | if (_pdfFont != null) { | 157 | if (_pdfFont != null) { |
| 158 | return _pdfFont!.fontName; | 158 | return _pdfFont!.fontName; |
| 159 | } | 159 | } |
| @@ -162,6 +162,18 @@ class TtfFont extends Font { | @@ -162,6 +162,18 @@ class TtfFont extends Font { | ||
| 162 | return font.fontName; | 162 | return font.fontName; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | + String? fontNameID(TtfParserName nameID) { | ||
| 166 | + final pdfFont = _pdfFont; | ||
| 167 | + if (pdfFont != null) { | ||
| 168 | + if (pdfFont is PdfTtfFont) { | ||
| 169 | + return pdfFont.font.getNameID(nameID); | ||
| 170 | + } | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + final font = TtfParser(data); | ||
| 174 | + return font.getNameID(nameID); | ||
| 175 | + } | ||
| 176 | + | ||
| 165 | @override | 177 | @override |
| 166 | String toString() { | 178 | String toString() { |
| 167 | final font = TtfParser(data); | 179 | final font = TtfParser(data); |
| @@ -58,7 +58,7 @@ void main() { | @@ -58,7 +58,7 @@ void main() { | ||
| 58 | build: (Context context) => ListView( | 58 | build: (Context context) => ListView( |
| 59 | children: <Widget>[ | 59 | children: <Widget>[ |
| 60 | Text( | 60 | Text( |
| 61 | - style.font!.fontName!, | 61 | + style.font!.fontName, |
| 62 | style: style, | 62 | style: style, |
| 63 | ), | 63 | ), |
| 64 | ], | 64 | ], |
-
Please register or login to post a comment