Skip to content
24 changes: 22 additions & 2 deletions src/DocMeasure.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,29 @@ class DocMeasure {
}

convertIfBase64Image(node) {
if (/^data:image\/(jpeg|jpg|png);base64,/.test(node.image)) { // base64 image
if (/^data:image\/(jpeg|jpg|png|svg+xml);base64,/.test(node.image)) { // base64 image
let label = `$$pdfmake$$${this.autoImageIndex++}`;
this.pdfDocument.images[label] = node.image;
node.image = label;
}
}

chekIfIsSVG(imageSource) {
// read the first 1000 bytes instead of 4 to allow for possible whitespace
return imageSource.toString('utf-8', 0, 1000).includes('<svg');
}

measureImage(node) {
this.convertIfBase64Image(node);
let imageSource = this.pdfDocument.provideImageSource(node.image);

if (this.chekIfIsSVG(imageSource)) {
delete node.image;
node.svg = imageSource.toString('utf-8');
return this.measureSVG(node);
}

let image = this.pdfDocument.provideImage(node.image);
let image = this.pdfDocument.provideImage(node.image, imageSource);
let imageSize = { width: image.width, height: image.height };

this.measureImageWithDimensions(node, imageSize);
Expand All @@ -133,6 +145,14 @@ class DocMeasure {
}

measureSVG(node) {
let imageSource = this.pdfDocument.provideImageSource(node.svg);

if (!this.chekIfIsSVG(imageSource)) {
throw new Error('DocMeasure.measureSVG: No valid SVG image provided');
} else {
node.svg = imageSource;
}

let dimensions = this.svgMeasure.measureSVG(node.svg);

this.measureImageWithDimensions(node, dimensions);
Expand Down
17 changes: 14 additions & 3 deletions src/PDFDocument.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ class PDFDocument extends PDFKit {
return this.fontCache[familyName][type];
}

provideImage(src) {
const realImageSrc = src => {
provideImageSource(src) {
const getRealImageSrc = src => {
let image = this.images[src];

if (!image) {
Expand All @@ -102,14 +102,25 @@ class PDFDocument extends PDFKit {
return Buffer.from(image.substring(index + 7), 'base64');
};

const realImageSrc = getRealImageSrc(src);

// convert to Buffer if in browser context
if (realImageSrc instanceof ArrayBuffer) {
return Buffer.from(new Uint8Array(realImageSrc));
}

return realImageSrc;
}

provideImage(src, imageSource) {
if (this._imageRegistry[src]) {
return this._imageRegistry[src];
}

let image;

try {
image = this.openImage(realImageSrc(src));
image = this.openImage(imageSource);
if (!image) {
throw new Error('No image');
}
Expand Down
4 changes: 4 additions & 0 deletions src/SVGMeasure.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class SVGMeasure {
writeDimensions(svgString, dimensions) {
let doc = parseSVG(svgString);

if ( typeof doc.attr.viewBox !== 'string' ) {
doc.attr.viewBox = `0 0 ${stripUnits(doc.attr.width)} ${stripUnits(doc.attr.height)}`;
}

doc.attr.width = "" + dimensions.width;
doc.attr.height = "" + dimensions.height;

Expand Down
3 changes: 3 additions & 0 deletions tests/unit/LayoutBuilder.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ var sampleTestProvider = {
descender: -50
};
},
provideImageSource(src) { // eslint-disable-line no-unused-vars
return {};
},
provideImage(src) { // eslint-disable-line no-unused-vars
return {
width: 1,
Expand Down