Read the text matrix from the Type1 font ascii header
This commit is contained in:
parent
ae2d130f40
commit
e13164eca6
65
fonts.js
65
fonts.js
@ -8,7 +8,7 @@ var isWorker = (typeof window == "undefined");
|
|||||||
/**
|
/**
|
||||||
* Maximum file size of the font.
|
* Maximum file size of the font.
|
||||||
*/
|
*/
|
||||||
var kMaxFontFileSize = 200000;
|
var kMaxFontFileSize = 40000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum time to wait for a font to be loaded by @font-face
|
* Maximum time to wait for a font to be loaded by @font-face
|
||||||
@ -77,6 +77,9 @@ var Fonts = (function Fonts() {
|
|||||||
measureCache = sizes[size] = Object.create(null);
|
measureCache = sizes[size] = Object.create(null);
|
||||||
ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"';
|
ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"';
|
||||||
},
|
},
|
||||||
|
getActive: function fonts_getActive() {
|
||||||
|
return current;
|
||||||
|
},
|
||||||
charsToUnicode: function fonts_chars2Unicode(chars) {
|
charsToUnicode: function fonts_chars2Unicode(chars) {
|
||||||
if (!charsCache)
|
if (!charsCache)
|
||||||
return chars;
|
return chars;
|
||||||
@ -1386,7 +1389,57 @@ var Type1Parser = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return extracted;
|
return extracted;
|
||||||
}
|
},
|
||||||
|
|
||||||
|
this.extractFontHeader = function t1_extractFontProgram(stream) {
|
||||||
|
var headerString = "";
|
||||||
|
for (var i = 0; i < stream.length; i++)
|
||||||
|
headerString += String.fromCharCode(stream[i]);
|
||||||
|
|
||||||
|
var info = {
|
||||||
|
textMatrix: null
|
||||||
|
};
|
||||||
|
|
||||||
|
function readNumberArray(str, index) {
|
||||||
|
var start = ++index;
|
||||||
|
var count = 0;
|
||||||
|
while ((c = str[index++]) != "]")
|
||||||
|
count++;
|
||||||
|
|
||||||
|
var array = str.substr(start, count).split(" ");
|
||||||
|
for (var i = 0; i < array.length; i++)
|
||||||
|
array[i] = parseFloat(array[i]);
|
||||||
|
return array;
|
||||||
|
};
|
||||||
|
|
||||||
|
var token = "";
|
||||||
|
var count = headerString.length;
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
var c = headerString[i];
|
||||||
|
if (c == " " || c == "\n") {
|
||||||
|
switch (token) {
|
||||||
|
case "/FontMatrix":
|
||||||
|
var matrix = readNumberArray(headerString, i + 1);
|
||||||
|
|
||||||
|
// The FontMatrix is in unitPerEm, so make it pixels
|
||||||
|
for (var j = 0; j < matrix.length; j++)
|
||||||
|
matrix[j] *= 1000;
|
||||||
|
|
||||||
|
// Make the angle into the right direction
|
||||||
|
matrix[2] *= -1;
|
||||||
|
|
||||||
|
info.textMatrix = matrix;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token = "";
|
||||||
|
} else {
|
||||||
|
token += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1457,7 +1510,12 @@ var CFF = function(name, file, properties) {
|
|||||||
// Get the data block containing glyphs and subrs informations
|
// Get the data block containing glyphs and subrs informations
|
||||||
var length1 = file.dict.get("Length1");
|
var length1 = file.dict.get("Length1");
|
||||||
var length2 = file.dict.get("Length2");
|
var length2 = file.dict.get("Length2");
|
||||||
file.skip(length1);
|
|
||||||
|
var headerBlock = file.getBytes(length1);
|
||||||
|
var header = type1Parser.extractFontHeader(headerBlock);
|
||||||
|
for (var info in header) {
|
||||||
|
properties[info] = header[info];
|
||||||
|
}
|
||||||
|
|
||||||
// Decrypt the data blocks and retrieve it's content
|
// Decrypt the data blocks and retrieve it's content
|
||||||
var eexecBlock = file.getBytes(length2);
|
var eexecBlock = file.getBytes(length2);
|
||||||
@ -1700,6 +1758,7 @@ CFF.prototype = {
|
|||||||
"charstrings": this.createCFFIndexHeader([[0x8B, 0x0E]].concat(glyphs), true),
|
"charstrings": this.createCFFIndexHeader([[0x8B, 0x0E]].concat(glyphs), true),
|
||||||
|
|
||||||
"private": (function(self) {
|
"private": (function(self) {
|
||||||
|
log(properties.stemSnapH);
|
||||||
var data =
|
var data =
|
||||||
"\x8b\x14" + // defaultWidth
|
"\x8b\x14" + // defaultWidth
|
||||||
"\x8b\x15" + // nominalWidth
|
"\x8b\x15" + // nominalWidth
|
||||||
|
6
pdf.js
6
pdf.js
@ -3544,7 +3544,8 @@ var CanvasGraphics = (function() {
|
|||||||
capHeight: descriptor.get("CapHeight"),
|
capHeight: descriptor.get("CapHeight"),
|
||||||
flags: descriptor.get("Flags"),
|
flags: descriptor.get("Flags"),
|
||||||
italicAngle: descriptor.get("ItalicAngle"),
|
italicAngle: descriptor.get("ItalicAngle"),
|
||||||
fixedPitch: false
|
fixedPitch: false,
|
||||||
|
textMatrix: IDENTITY_MATRIX.slice()
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -3861,7 +3862,6 @@ var CanvasGraphics = (function() {
|
|||||||
// TODO: apply charSpacing, wordSpacing, textHScale
|
// TODO: apply charSpacing, wordSpacing, textHScale
|
||||||
|
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
this.ctx.transform.apply(this.ctx, this.current.textMatrix);
|
|
||||||
this.ctx.scale(1, -1);
|
this.ctx.scale(1, -1);
|
||||||
|
|
||||||
if (this.ctx.$showText) {
|
if (this.ctx.$showText) {
|
||||||
@ -3869,6 +3869,8 @@ var CanvasGraphics = (function() {
|
|||||||
} else {
|
} else {
|
||||||
text = Fonts.charsToUnicode(text);
|
text = Fonts.charsToUnicode(text);
|
||||||
this.ctx.translate(this.current.x, -1 * this.current.y);
|
this.ctx.translate(this.current.x, -1 * this.current.y);
|
||||||
|
var matrix = Fonts.lookup(this.current.fontName).properties.textMatrix;
|
||||||
|
this.ctx.transform.apply(this.ctx, matrix);
|
||||||
this.ctx.fillText(text, 0, 0);
|
this.ctx.fillText(text, 0, 0);
|
||||||
this.current.x += Fonts.measureText(text);
|
this.current.x += Fonts.measureText(text);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user