Socket
Socket
Sign inDemoInstall

svgo

Package Overview
Dependencies
17
Maintainers
1
Versions
103
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.9 to 0.2.0

plugins/_transforms.js

7

CHANGELOG.md

@@ -0,1 +1,8 @@

### [ [>](https://github.com/svg/svgo/tree/v0.2.0) ] 0.2.0 / 23.12.2012
* plugins/convertPathData: apply transforms to Path pata (close [#33](https://github.com/svg/svgo/issues/33))
* plugins/convertPathData: `-1.816-9.278.682-13.604` parsing error (fix [#85](https://github.com/svg/svgo/issues/85))
* plugins/convertTransform: `translate(10, 0)` eq `translate(10)`, but not `translate(10, 10)` eq `translate(10)` (fix [#83](https://github.com/svg/svgo/issues/83))
* run plugins/cleanupIDs before plugins/collapseGroups (fix [#84](https://github.com/svg/svgo/issues/84))
* update `.gitignore`
### [ [>](https://github.com/svg/svgo/tree/v0.1.9) ] 0.1.9 / 17.12.2012

@@ -2,0 +9,0 @@ * plugins/cleanupIDs: renamed from removeUnusedIDs; minify used IDs (fix [#7](https://github.com/svg/svgo/issues/7))

16

lib/svgo/tools.js

@@ -57,3 +57,4 @@ 'use strict';

var str = '',
delimiter;
delimiter,
prev;

@@ -70,7 +71,16 @@ data.forEach(function(item, i) {

// no extra space in front of negative number
if (params.negativeExtraSpace && item < 0) {
// no extra space in front of negative number or
// in front of a floating number if a previous number is floating too
if (
params.negativeExtraSpace &&
(item < 0 ||
(item > 0 && item < 1 && prev % 1 !== 0)
)
) {
delimiter = '';
}
// save prev item value
prev = item;
// remove floating-point numbers leading zeros

@@ -77,0 +87,0 @@ // 0.5 → .5

4

package.json
{
"name": "svgo",
"version": "0.1.9",
"version": "0.2.0",
"description": "Nodejs-based tool for optimizing SVG vector graphics files",

@@ -9,3 +9,3 @@ "keywords": [ "svgo", "svg", "optimize", "minify" ],

"url": "https://github.com/svg/svgo/issues",
"email": "svgo@soulshine.in"
"email": "kir@soulshine.in"
},

@@ -12,0 +12,0 @@ "author": {

@@ -5,5 +5,7 @@ 'use strict';

regPathInstructions = /([MmLlHhVvCcSsQqTtAaZz])\s*/,
regPathData = /[\-+]?\d*\.?\d+(\.\d+)?([eE][\-+]?\d+)?/g,
regPathData = /[\-+]?\d*\.?\d+([eE][\-+]?\d+)?/g,
pathElems = ['path', 'glyph', 'missing-glyph'],
hasMarkerMid;
hasMarkerMid,
transform2js = require('./_transforms.js').transform2js,
transformsMultiply = require('./_transforms.js').transformsMultiply;

@@ -34,8 +36,16 @@ /**

// TODO: get rid of functions returns
if (data.length) {
data = convertToRelative(data);
if (params.applyTransforms) {
data = applyTransforms(item, data);
}
data = filters(data, params);
data = collapseRepeated(data, params);
if (params.collapseRepeated) {
data = collapseRepeated(data, params);
}

@@ -54,3 +64,2 @@ item.attr('d').value = js2path(data, params);

* @param {Object} params plugin params
*
* @return {Array} output array

@@ -144,3 +153,2 @@ */

* @param {Object} params plugin params
*
* @return {Array} output path data

@@ -306,2 +314,107 @@ */

/**
* Apply transformation(s) to the Path data.
*
* @param {Object} elem current element
* @param {Array} path input path data
* @return {Array} output path data
*/
function applyTransforms(elem, path) {
// if there are no 'stroke' attr and 'a' segments
if (
elem.hasAttr('transform') &&
!elem.hasAttr('stroke') &&
path.every(function(i) { return i.instruction !== 'a'; })
) {
var matrix = transformsMultiply(transform2js(elem.attr('transform').value)),
currentPoint;
// if there is a translate() transform
if (matrix.data[4] !== 0 || matrix.data[5] !== 0) {
// then apply it only to the first absoluted M
currentPoint = transformPoint(matrix.data, path[0].data[0], path[0].data[1]);
path[0].data[0] = currentPoint[0];
path[0].data[1] = currentPoint[1];
// clear translate() data from transform matrix
matrix.data[4] = 0;
matrix.data[5] = 0;
// apply transform to other segments
path.slice(1).forEach(function(pathItem) {
pathItem = transformData(matrix, pathItem);
});
} else {
path.forEach(function(pathItem) {
pathItem = transformData(matrix, pathItem);
});
}
// remove transform attr
elem.removeAttr('transform');
}
return path;
}
/**
* Apply transformation(s) to the Path item data.
*
* @param {Array} matrix transform 3x3 matrix
* @param {Object} item input Path item
* @return {Object} output Path item
*/
function transformData(matrix, item) {
if (item.data) {
var currentPoint;
// h
if (item.instruction === 'h') {
item.instruction = 'l';
item.data[1] = 0;
// v
} else if (item.instruction === 'v') {
item.instruction = 'l';
item.data[1] = item.data[0];
item.data[0] = 0;
}
for (var i = 0; i < item.data.length; i += 2) {
currentPoint = transformPoint(matrix.data, item.data[i], item.data[i + 1]);
item.data[i] = currentPoint[0];
item.data[i + 1] = currentPoint[1];
}
}
return item;
}
/**
* Apply transform 3x3 matrix to x-y point.
*
* @param {Array} matrix transform 3x3 matrix
* @param {Array} point x-y point
* @return {Array} point with new coordinates
*/
function transformPoint(matrix, x, y) {
return [
matrix[0] * x + matrix[2] * y + matrix[4],
matrix[1] * x + matrix[3] * y + matrix[5]
];
}
/**
* Main filters loop.

@@ -311,3 +424,2 @@ *

* @param {Object} params plugin params
*
* @return {Array} output path data

@@ -546,3 +658,2 @@ */

// collapse repeated instructions data
/**

@@ -552,38 +663,32 @@ * Collapse repeated instructions data

* @param {Array} path input path data
* @param {Object} params plugin params
*
* @return {Array} output path data
*/
function collapseRepeated(path, params) {
function collapseRepeated(path) {
if (params.collapseRepeated) {
var prev;
var prev;
path = path.filter(function(item) {
path = path.filter(function(item) {
if (
!hasMarkerMid &&
prev &&
item.instruction === prev.instruction
) {
// increase previous h or v data with current
if (item.instruction === 'h' || item.instruction === 'v') {
prev.data[0] += item.data[0];
// concat previous data with current
} else {
prev.data = prev.data.concat(item.data);
}
// filter current item
return false;
if (
!hasMarkerMid &&
prev &&
item.instruction === prev.instruction
) {
// increase previous h or v data with current
if (item.instruction === 'h' || item.instruction === 'v') {
prev.data[0] += item.data[0];
// concat previous data with current
} else {
prev.data = prev.data.concat(item.data);
}
prev = item;
// filter current item
return false;
}
return true;
prev = item;
});
return true;
}
});

@@ -600,3 +705,2 @@ return path;

* @param {Number} fixed number of decimals
*
* @return {Array} output data array

@@ -619,3 +723,2 @@ */

* @param {Array} ys array of curve points y-coordinates
*
* @return {Boolean}

@@ -646,3 +749,2 @@ */

* @param {Object} params plugin params
*
* @return {String} output path string

@@ -652,3 +754,3 @@ */

// out path data string
// output path data string
var pathString = '';

@@ -655,0 +757,0 @@

'use strict';
var cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
regTransformTypes = /matrix|translate|scale|rotate|skewX|skewY/,
regTransformSplit = /(matrix|translate|scale|rotate|skewX|skewY)\s*\((.+?)\)[\s,]*/,
regTransformDataSplit = /[\s,]+/;
transform2js = require('./_transforms.js').transform2js,
transformsMultiply = require('./_transforms.js').transformsMultiply,
matrixToTransform = require('./_transforms.js').matrixToTransform;

@@ -64,4 +64,13 @@ /**

if (params.collapseIntoOne) {
data = collapseIntoOne(data, params);
if (
params.collapseIntoOne &&
(data.length >= 3 ||
data.some(function(i) { return i.name === 'matrix'; })
)
) {
data = [transformsMultiply(data, params)];
if (params.matrixToTransform) {
data = [matrixToTransform(data[0], params)];
}
}

@@ -74,42 +83,2 @@

/**
* Convert transform string to JS representation.
*
* @param {String} transformString input string
* @param {Object} params plugin params
*
* @return {Array} output array
*/
function transform2js(transformString) {
// JS representation of the transform data
var transforms = [],
// current transform context
current;
// split value into ['', 'translate', '10 50', '', 'scale', '2', '', 'rotate', '-45', '']
transformString.split(regTransformSplit).forEach(function(item) {
if (item) {
// if item is a translate function
if (regTransformTypes.test(item)) {
// then collect it and change current context
transforms.push(current = {
name: item
});
// else if item is data
} else {
// then split it into [10, 50] and collect as context.data
current.data = item.split(regTransformDataSplit).map(function(i) {
return +i;
});
}
}
});
return transforms;
}
/**
* Convert transforms to the shorthand alternatives.

@@ -119,3 +88,2 @@ *

* @param {Object} params plugin params
*
* @return {Array} output array

@@ -146,11 +114,24 @@ */

// convert long translate or scale transform notations to the shorts ones
// convert long translate transform notation to the shorts one
// translate(10 0) → translate(10)
if (
params.shortTranslateScale &&
(transform.name === 'translate' ||
transform.name === 'scale')
params.shortTranslate &&
transform.name === 'translate' &&
transform.data.length === 2 &&
transform.data[1] === 0
) {
transform.data = longTranslateScaleToShort(transform.data);
transform.data = [transform.data[0]];
}
// convert long scale transform notation to the shorts one
// scale(2 2) → scale(2)
if (
params.shortScale &&
transform.name === 'scale' &&
transform.data.length === 2 &&
transform.data[0] === transform.data[1]
) {
transform.data = [transform.data[0]];
}
// convert long rotate transform notation to the short one

@@ -192,3 +173,2 @@ // translate(cx cy) rotate(a) translate(-cx -cy) → rotate(a cx cy)

* @param {Array} transforms input array
*
* @return {Array} output array

@@ -223,45 +203,2 @@ */

/**
* Collapse multiple transforms into one.
*
* @param {Array} transforms input array
* @param {Object} params plugin params
*
* @return {Array} output array
*/
function collapseIntoOne(transforms, params) {
if (
(transforms.length >= 3 ||
transforms.some(function(i) { return i.name === 'matrix'; }))
) {
// convert transforms objects to the matrices
transforms = transforms.map(function(transform) {
return transform.name === 'martix' ?
transform :
transformToMatrix(transform, params);
});
// multiply all matrices into one
transforms = {
name: 'matrix',
data: transforms.reduce(function(a, b) {
return multiplyTransformMatrices(a, b);
})
};
// and try to get a jackpot
if (params.matrixToTransform) {
transforms = matrixToTransform(transforms, params);
}
transforms = [transforms];
}
return transforms;
}
/**
* Convert transforms JS representation to string.

@@ -271,3 +208,2 @@ *

* @param {Object} params plugin params
*
* @return {String} output string

@@ -291,161 +227,2 @@ */

/**
* Do math like a schoolgirl.
*
* @type {Object}
*/
var mth = {
rad: function(deg) {
return deg * Math.PI / 180;
},
deg: function(rad) {
return rad * 180 / Math.PI;
},
cos: function(deg) {
return Math.cos(this.rad(deg));
},
acos: function(val, floatPrecision) {
return +(this.deg(Math.acos(val)).toFixed(floatPrecision));
},
sin: function(deg) {
return Math.sin(this.rad(deg));
},
asin: function(val, floatPrecision) {
return +(this.deg(Math.asin(val)).toFixed(floatPrecision));
},
tan: function(deg) {
return Math.tan(this.rad(deg));
},
atan: function(val, floatPrecision) {
return +(this.deg(Math.atan(val)).toFixed(floatPrecision));
}
};
/**
* Convert transform to the matrix data.
*
* @param {Object} transform transform object
*
* @return {Array} matrix data
*/
function transformToMatrix(transform) {
if (transform.name === 'matrix') return transform.data;
var matrix;
switch(transform.name) {
case 'translate':
// [1, 0, 0, 1, tx, ty]
matrix = [1, 0, 0, 1, transform.data[0], transform.data[1] || transform.data[0]];
break;
case 'scale':
// [sx, 0, 0, sy, 0, 0]
matrix = [transform.data[0], 0, 0, transform.data[1] || transform.data[0], 0, 0];
break;
case 'rotate':
// [cos(a), sin(a), -sin(a), cos(a), 0, 0]
var cos = mth.cos(transform.data[0]),
sin = mth.sin(transform.data[0]);
matrix = [cos, sin, -sin, cos, 0, 0];
break;
case 'skewX':
// [1, 0, tan(a), 1, 0, 0]
matrix = [1, 0, mth.tan(transform.data[0]), 1, 0, 0];
break;
case 'skewY':
// [1, tan(a), 0, 1, 0, 0]
matrix = [1, mth.tan(transform.data[0]), 0, 1, 0, 0];
break;
}
return matrix;
}
/**
* Convert matrix data to the transform alias.
*
* @param {Object} data matrix transform object
*
* @return {Object} transform object
*/
function matrixToTransform(transform, params) {
var data = transform.data;
// [1, 0, 0, 1, tx, ty] → translate(tx, ty)
if (
data[0] === 1 &&
data[1] === 0 &&
data[2] === 0 &&
data[3] === 1
) {
transform.name = 'translate';
transform.data = [data[4], data[5]];
// [sx, 0, 0, sy, 0, 0] → scale(sx, sy)
} else if (
data[1] === 0 &&
data[2] === 0 &&
data[4] === 0 &&
data[5] === 0
) {
transform.name = 'scale';
transform.data = [data[0], data[3]];
// [cos(a), sin(a), -sin(a), cos(a), 0 0] → rotate(a)
} else if (
data[0] === data[3] &&
data[1] === -data[2] &&
data[4] === 0 &&
data[5] === 0
) {
var a1 = mth.acos(data[0], params.floatPrecision),
a2 = mth.asin(data[1], params.floatPrecision);
a1 = a2 < 0 ? -a1 : a1;
if (Math.round(a1) === Math.round(a2)) {
transform.name = 'rotate';
transform.data = [a1];
}
// [1, 0, tan(a), 1, 0, 0] → skewX(a)
} else if (
data[0] === 1 &&
data[1] === 0 &&
data[3] === 1 &&
data[4] === 0 &&
data[5] === 0
) {
transform.name = 'skewX';
transform.data = [mth.atan(data[2], params.floatPrecision)];
// [1, tan(a), 0, 1, 0, 0] → skewY(a)
} else if (
data[0] === 1 &&
data[2] === 0 &&
data[3] === 1 &&
data[4] === 0 &&
data[5] === 0
) {
transform.name = 'skewY';
transform.data = [mth.atan(data[1], params.floatPrecision)];
}
return transform;
}
/**
* Convert long translate or scale transforms to the shorts ones.

@@ -468,22 +245,1 @@ *

}
/**
* Multiply transformation matrices.
*
* @param {Array} a matrix A data
* @param {Array} b matrix B data
*
* @return {Array} result
*/
function multiplyTransformMatrices(a, b) {
return [
+(a[0] * b[0] + a[2] * b[1]).toFixed(3),
+(a[1] * b[0] + a[3] * b[1]).toFixed(3),
+(a[0] * b[2] + a[2] * b[3]).toFixed(3),
+(a[1] * b[2] + a[3] * b[3]).toFixed(3),
+(a[0] * b[4] + a[2] * b[5] + a[4]).toFixed(3),
+(a[1] * b[4] + a[3] * b[5] + a[5]).toFixed(3)
];
}

@@ -6,3 +6,3 @@ **english** | [русский](https://github.com/svg/svgo/blob/master/README.ru.md)

## SVGO v0.1.9 [![Build Status](https://secure.travis-ci.org/svg/svgo.png)](http://travis-ci.org/svg/svgo)
## SVGO v0.2.0 [![Build Status](https://secure.travis-ci.org/svg/svgo.png)](http://travis-ci.org/svg/svgo)

@@ -9,0 +9,0 @@ **SVG O**ptimizer is a Nodejs-based tool for optimizing SVG vector graphics files.

@@ -6,3 +6,3 @@ [english](https://github.com/svg/svgo/blob/master/README.md) | **русский**

## SVGO v0.1.9 [![Build Status](https://secure.travis-ci.org/svg/svgo.png)](http://travis-ci.org/svg/svgo)
## SVGO v0.2.0 [![Build Status](https://secure.travis-ci.org/svg/svgo.png)](http://travis-ci.org/svg/svgo)

@@ -9,0 +9,0 @@ **SVG** **O**ptimizer – это инструмент для оптимизации векторной графики в формате SVG, написанный на Node.js.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc