Merge pull request #556 from notmasteryet/cid0
Initial CID-0 font encodings
This commit is contained in:
commit
7842c65099
6932
cidmaps.js
Normal file
6932
cidmaps.js
Normal file
File diff suppressed because it is too large
Load Diff
109
fonts.js
109
fonts.js
@ -429,6 +429,9 @@ var Font = (function Font() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Trying to fix encoding using glyph widths and CIDSystemInfo.
|
||||
this.fixWidths(properties);
|
||||
|
||||
if (!file) {
|
||||
// The file data is not specified. Trying to fix the font name
|
||||
// to be used with the canvas.font.
|
||||
@ -443,6 +446,7 @@ var Font = (function Font() {
|
||||
|
||||
this.defaultWidth = properties.defaultWidth;
|
||||
this.loadedName = fontName.split('-')[0];
|
||||
this.composite = properties.composite;
|
||||
this.loading = false;
|
||||
return;
|
||||
}
|
||||
@ -1208,25 +1212,11 @@ var Font = (function Font() {
|
||||
}
|
||||
|
||||
var encoding = properties.encoding, i;
|
||||
if (!encoding[0]) {
|
||||
// the font is directly characters to glyphs with no encoding
|
||||
// so create an identity encoding
|
||||
var widths = properties.widths;
|
||||
for (i = 0; i < numGlyphs; i++) {
|
||||
var width = widths[i];
|
||||
encoding[i] = {
|
||||
unicode: i <= 0x1f || (i >= 127 && i <= 255) ?
|
||||
i + kCmapGlyphOffset : i,
|
||||
width: isNum(width) ? width : properties.defaultWidth
|
||||
};
|
||||
}
|
||||
} else {
|
||||
for (i in encoding) {
|
||||
if (encoding.hasOwnProperty(i)) {
|
||||
var unicode = encoding[i].unicode;
|
||||
if (unicode <= 0x1f || (unicode >= 127 && unicode <= 255))
|
||||
encoding[i].unicode = unicode += kCmapGlyphOffset;
|
||||
}
|
||||
for (i in encoding) {
|
||||
if (encoding.hasOwnProperty(i)) {
|
||||
var unicode = encoding[i].unicode;
|
||||
if (unicode <= 0x1f || (unicode >= 127 && unicode <= 255))
|
||||
encoding[i].unicode = unicode += kCmapGlyphOffset;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1402,6 +1392,87 @@ var Font = (function Font() {
|
||||
return stringToArray(otf.file);
|
||||
},
|
||||
|
||||
fixWidths: function font_fixWidths(properties) {
|
||||
if (properties.type !== 'CIDFontType0' &&
|
||||
properties.type !== 'CIDFontType2')
|
||||
return;
|
||||
|
||||
var encoding = properties.encoding;
|
||||
if (encoding[0])
|
||||
return;
|
||||
var glyphsWidths = properties.widths;
|
||||
if (!glyphsWidths)
|
||||
return;
|
||||
|
||||
var defaultWidth = properties.defaultWidth;
|
||||
var cidSystemInfo = properties.cidSystemInfo;
|
||||
var cidToUnicode;
|
||||
if (cidSystemInfo) {
|
||||
cidToUnicode = CIDToUnicodeMaps[
|
||||
cidSystemInfo.registry + '-' + cidSystemInfo.ordering];
|
||||
}
|
||||
if (!cidToUnicode) {
|
||||
// the font is directly characters to glyphs with no encoding
|
||||
// so create an identity encoding
|
||||
for (i = 0; i < 0xD800; i++) {
|
||||
var width = glyphsWidths[i];
|
||||
encoding[i] = {
|
||||
unicode: i,
|
||||
width: isNum(width) ? width : defaultWidth
|
||||
};
|
||||
}
|
||||
// skipping surrogates + 256-user defined
|
||||
for (i = 0xE100; i <= 0xFFFF; i++) {
|
||||
var width = glyphsWidths[i];
|
||||
encoding[i] = {
|
||||
unicode: i,
|
||||
width: isNum(width) ? width : defaultWidth
|
||||
};
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
encoding[0] = { unicode: 0, width: 0 };
|
||||
var glyph = 1, i, j, k;
|
||||
for (i = 0; i < cidToUnicode.length; ++i) {
|
||||
var unicode = cidToUnicode[i];
|
||||
var width;
|
||||
if (isArray(unicode)) {
|
||||
var length = unicode.length;
|
||||
width = glyphsWidths[glyph];
|
||||
for (j = 0; j < length; j++) {
|
||||
k = unicode[j];
|
||||
encoding[k] = {
|
||||
unicode: k,
|
||||
width: isNum(width) ? width : defaultWidth
|
||||
};
|
||||
}
|
||||
glyph++;
|
||||
} else if (typeof unicode === 'object') {
|
||||
var fillLength = unicode.f;
|
||||
if (fillLength) {
|
||||
k = unicode.c;
|
||||
for (j = 0; j < fillLength; ++j) {
|
||||
width = glyphsWidths[glyph++];
|
||||
encoding[k] = {
|
||||
unicode: k,
|
||||
width: isNum(width) ? width : defaultWidth
|
||||
};
|
||||
k++;
|
||||
}
|
||||
} else
|
||||
glyph += unicode.s;
|
||||
} else if (unicode) {
|
||||
width = glyphsWidths[glyph++];
|
||||
encoding[unicode] = {
|
||||
unicode: unicode,
|
||||
width: isNum(width) ? width : defaultWidth
|
||||
};
|
||||
} else
|
||||
glyph++;
|
||||
}
|
||||
},
|
||||
|
||||
bindWorker: function font_bindWorker(data) {
|
||||
postMessage({
|
||||
action: 'font',
|
||||
|
120
pdf.js
120
pdf.js
@ -4455,72 +4455,70 @@ var PartialEvaluator = (function partialEvaluator() {
|
||||
properties) {
|
||||
var type = properties.type, encoding;
|
||||
if (properties.composite) {
|
||||
if (type == 'CIDFontType2') {
|
||||
var defaultWidth = xref.fetchIfRef(dict.get('DW')) || 1000;
|
||||
properties.defaultWidth = defaultWidth;
|
||||
var defaultWidth = xref.fetchIfRef(dict.get('DW')) || 1000;
|
||||
properties.defaultWidth = defaultWidth;
|
||||
|
||||
var glyphsWidths = {};
|
||||
var widths = xref.fetchIfRef(dict.get('W'));
|
||||
if (widths) {
|
||||
var start = 0, end = 0;
|
||||
for (var i = 0; i < widths.length; i++) {
|
||||
var code = widths[i];
|
||||
if (isArray(code)) {
|
||||
for (var j = 0; j < code.length; j++)
|
||||
glyphsWidths[start++] = code[j];
|
||||
start = 0;
|
||||
} else if (start) {
|
||||
var width = widths[++i];
|
||||
for (var j = start; j <= code; j++)
|
||||
glyphsWidths[j] = width;
|
||||
start = 0;
|
||||
} else {
|
||||
start = code;
|
||||
}
|
||||
}
|
||||
}
|
||||
properties.widths = glyphsWidths;
|
||||
|
||||
var cidToGidMap = dict.get('CIDToGIDMap');
|
||||
if (!cidToGidMap || !isRef(cidToGidMap)) {
|
||||
return Object.create(GlyphsUnicode);
|
||||
}
|
||||
|
||||
// Extract the encoding from the CIDToGIDMap
|
||||
var glyphsStream = xref.fetchIfRef(cidToGidMap);
|
||||
var glyphsData = glyphsStream.getBytes(0);
|
||||
|
||||
// Glyph ids are big-endian 2-byte values
|
||||
encoding = properties.encoding;
|
||||
|
||||
// Set encoding 0 to later verify the font has an encoding
|
||||
encoding[0] = { unicode: 0, width: 0 };
|
||||
for (var j = 0; j < glyphsData.length; j++) {
|
||||
var glyphID = (glyphsData[j++] << 8) | glyphsData[j];
|
||||
if (glyphID == 0)
|
||||
continue;
|
||||
|
||||
var code = j >> 1;
|
||||
var width = glyphsWidths[code];
|
||||
encoding[code] = {
|
||||
unicode: glyphID,
|
||||
width: isNum(width) ? width : defaultWidth
|
||||
};
|
||||
}
|
||||
} else if (type == 'CIDFontType0') {
|
||||
if (isName(encoding)) {
|
||||
// Encoding is a predefined CMap
|
||||
if (encoding.name == 'Identity-H') {
|
||||
TODO('Need to create an identity cmap');
|
||||
var glyphsWidths = {};
|
||||
var widths = xref.fetchIfRef(dict.get('W'));
|
||||
if (widths) {
|
||||
var start = 0, end = 0;
|
||||
for (var i = 0; i < widths.length; i++) {
|
||||
var code = widths[i];
|
||||
if (isArray(code)) {
|
||||
for (var j = 0; j < code.length; j++)
|
||||
glyphsWidths[start++] = code[j];
|
||||
start = 0;
|
||||
} else if (start) {
|
||||
var width = widths[++i];
|
||||
for (var j = start; j <= code; j++)
|
||||
glyphsWidths[j] = width;
|
||||
start = 0;
|
||||
} else {
|
||||
TODO('Need to support predefined CMaps see PDF 32000-1:2008 ' +
|
||||
'9.7.5.2 Predefined CMaps');
|
||||
start = code;
|
||||
}
|
||||
} else {
|
||||
TODO('Need to support encoding streams see PDF 32000-1:2008 ' +
|
||||
'9.7.5.3');
|
||||
}
|
||||
}
|
||||
properties.widths = glyphsWidths;
|
||||
|
||||
// Glyph ids are big-endian 2-byte values
|
||||
encoding = properties.encoding;
|
||||
|
||||
// CIDSystemInfo might help to match width and glyphs
|
||||
var cidSystemInfo = dict.get('CIDSystemInfo');
|
||||
if (isDict(cidSystemInfo)) {
|
||||
properties.cidSystemInfo = {
|
||||
registry: cidSystemInfo.get('Registry'),
|
||||
ordering: cidSystemInfo.get('Ordering'),
|
||||
supplement: cidSystemInfo.get('Supplement')
|
||||
};
|
||||
}
|
||||
|
||||
var cidToGidMap = dict.get('CIDToGIDMap');
|
||||
if (!cidToGidMap || !isRef(cidToGidMap)) {
|
||||
|
||||
|
||||
return Object.create(GlyphsUnicode);
|
||||
}
|
||||
|
||||
// Extract the encoding from the CIDToGIDMap
|
||||
var glyphsStream = xref.fetchIfRef(cidToGidMap);
|
||||
var glyphsData = glyphsStream.getBytes(0);
|
||||
|
||||
// Set encoding 0 to later verify the font has an encoding
|
||||
encoding[0] = { unicode: 0, width: 0 };
|
||||
for (var j = 0; j < glyphsData.length; j++) {
|
||||
var glyphID = (glyphsData[j++] << 8) | glyphsData[j];
|
||||
if (glyphID == 0)
|
||||
continue;
|
||||
|
||||
var code = j >> 1;
|
||||
var width = glyphsWidths[code];
|
||||
encoding[code] = {
|
||||
unicode: glyphID,
|
||||
width: isNum(width) ? width : defaultWidth
|
||||
};
|
||||
}
|
||||
|
||||
return Object.create(GlyphsUnicode);
|
||||
}
|
||||
|
||||
|
1
test/pdfs/tcpdf_033.pdf.link
Normal file
1
test/pdfs/tcpdf_033.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
http://www.tcpdf.org/examples/example_033.pdf
|
@ -170,5 +170,11 @@
|
||||
"rounds": 1,
|
||||
"skipPages": [ 16 ],
|
||||
"type": "load"
|
||||
},
|
||||
{ "id": "tcpdf_033",
|
||||
"file": "pdfs/tcpdf_033.pdf",
|
||||
"link": true,
|
||||
"rounds": 1,
|
||||
"type": "eq"
|
||||
}
|
||||
]
|
||||
|
@ -8,6 +8,7 @@
|
||||
<script type="text/javascript" src="/glyphlist.js"></script>
|
||||
<script type="text/javascript" src="/metrics.js"></script>
|
||||
<script type="text/javascript" src="/charsets.js"></script>
|
||||
<script type="text/javascript" src="/cidmaps.js"></script>
|
||||
<script type="text/javascript" src="driver.js"></script>
|
||||
</head>
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
<script type="text/javascript" src="../glyphlist.js"></script>
|
||||
<script type="text/javascript" src="../metrics.js"></script>
|
||||
<script type="text/javascript" src="../charsets.js"></script>
|
||||
<script type="text/javascript" src="../cidmaps.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
Loading…
x
Reference in New Issue
Block a user