David PHAM-VAN

Fix font writer CMAP

# Changelog
## 1.10.1
- Fix TTF writer with more than 256 CMAP entries
## 1.10.0
- Fix dependencies
... ...
... ... @@ -137,49 +137,52 @@ class TtfParser {
for (int i = 0; i < numSubTables; i++) {
final int offset = bytes.getUint32(basePosition + i * 8 + 8);
final int format = bytes.getUint16(basePosition + offset);
final int length = bytes.getUint16(basePosition + offset + 2);
switch (format) {
case 0:
_parseCMapFormat0(basePosition + offset + 4, length);
_parseCMapFormat0(basePosition + offset + 2);
break;
case 4:
_parseCMapFormat4(basePosition + offset + 4, length);
_parseCMapFormat4(basePosition + offset + 2);
break;
case 6:
_parseCMapFormat6(basePosition + offset + 4, length);
_parseCMapFormat6(basePosition + offset + 2);
break;
case 12:
_parseCMapFormat12(basePosition + offset + 2);
break;
}
}
}
void _parseCMapFormat0(int basePosition, int length) {
assert(length == 262);
void _parseCMapFormat0(int basePosition) {
assert(bytes.getUint16(basePosition) == 262);
for (int i = 0; i < 256; i++) {
final int charCode = i;
final int glyphIndex = bytes.getUint8(basePosition + i);
final int glyphIndex = bytes.getUint8(basePosition + i + 2);
if (glyphIndex > 0) {
charToGlyphIndexMap[charCode] = glyphIndex;
}
}
}
void _parseCMapFormat4(int basePosition, int length) {
final int segCount = bytes.getUint16(basePosition + 2) ~/ 2;
void _parseCMapFormat4(int basePosition) {
final int segCount = bytes.getUint16(basePosition + 4) ~/ 2;
final List<int> endCodes = <int>[];
for (int i = 0; i < segCount; i++) {
endCodes.add(bytes.getUint16(basePosition + i * 2 + 10));
endCodes.add(bytes.getUint16(basePosition + i * 2 + 12));
}
final List<int> startCodes = <int>[];
for (int i = 0; i < segCount; i++) {
startCodes.add(bytes.getUint16(basePosition + (segCount + i) * 2 + 12));
startCodes.add(bytes.getUint16(basePosition + (segCount + i) * 2 + 14));
}
final List<int> idDeltas = <int>[];
for (int i = 0; i < segCount; i++) {
idDeltas.add(bytes.getUint16(basePosition + (segCount * 2 + i) * 2 + 12));
idDeltas.add(bytes.getUint16(basePosition + (segCount * 2 + i) * 2 + 14));
}
final int idRangeOffsetBasePos = basePosition + segCount * 6 + 12;
final int idRangeOffsetBasePos = basePosition + segCount * 6 + 14;
final List<int> idRangeOffsets = <int>[];
for (int i = 0; i < segCount; i++) {
idRangeOffsets.add(bytes.getUint16(idRangeOffsetBasePos + i * 2));
... ... @@ -204,18 +207,35 @@ class TtfParser {
}
}
void _parseCMapFormat6(int basePosition, int length) {
final int firstCode = bytes.getUint16(basePosition + 2);
final int entryCount = bytes.getUint16(basePosition + 4);
void _parseCMapFormat6(int basePosition) {
final int firstCode = bytes.getUint16(basePosition + 4);
final int entryCount = bytes.getUint16(basePosition + 6);
for (int i = 0; i < entryCount; i++) {
final int charCode = firstCode + i;
final int glyphIndex = bytes.getUint16(basePosition + i * 2 + 6);
final int glyphIndex = bytes.getUint16(basePosition + i * 2 + 8);
if (glyphIndex > 0) {
charToGlyphIndexMap[charCode] = glyphIndex;
}
}
}
void _parseCMapFormat12(int basePosition) {
final int numGroups = bytes.getUint32(basePosition + 10);
assert(bytes.getUint32(basePosition + 2) == 12 * numGroups + 16);
for (int i = 0; i < numGroups; i++) {
final int startCharCode = bytes.getUint32(basePosition + i * 12 + 14);
final int endCharCode = bytes.getUint32(basePosition + i * 12 + 18);
final int startGlyphID = bytes.getUint32(basePosition + i * 12 + 22);
for (int j = startCharCode; j <= endCharCode; j++) {
assert(!charToGlyphIndexMap.containsKey(j) ||
charToGlyphIndexMap[j] == startGlyphID + j - startCharCode);
charToGlyphIndexMap[j] = startGlyphID + j - startCharCode;
}
}
}
void _parseIndexes() {
final int basePosition = tableOffsets[loca_table];
final int numGlyphs = this.numGlyphs;
... ...
... ... @@ -196,14 +196,24 @@ class TtfWriter {
{
// CMAP table
final Uint8List cmap = Uint8List(_wordAlign(0x112, 4));
cmap.setAll(3, <int>[1, 0, 1, 0, 0, 0, 0, 0, 12, 0, 0, 1, 6]);
const int len = 40;
final Uint8List cmap = Uint8List(_wordAlign(len, 4));
final ByteData cmapData = cmap.buffer.asByteData();
for (int i = 1; i < chars.length; i++) {
cmapData.setUint8(i + 18, i);
}
cmapData.setUint16(0, 0); // Table version number
cmapData.setUint16(2, 1); // Number of encoding tables that follow.
cmapData.setUint16(4, 3); // Platform ID
cmapData.setUint16(6, 1); // Platform-specific encoding ID
cmapData.setUint32(8, 12); // Offset from beginning of table
cmapData.setUint16(12, 12); // Table format
cmapData.setUint32(16, 28); // Table length
cmapData.setUint32(20, 1); // Table language
cmapData.setUint32(24, 1); // numGroups
cmapData.setUint32(28, 32); // startCharCode
cmapData.setUint32(32, chars.length + 31); // endCharCode
cmapData.setUint32(36, 0); // startGlyphID
tables[TtfParser.cmap_table] = cmap;
tablesLength[TtfParser.cmap_table] = 0x112;
tablesLength[TtfParser.cmap_table] = len;
}
{
... ...
... ... @@ -4,7 +4,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl
homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf
repository: https://github.com/DavBfr/dart_pdf
issue_tracker: https://github.com/DavBfr/dart_pdf/issues
version: 1.10.0
version: 1.10.1
environment:
sdk: ">=2.3.0 <3.0.0"
... ...