This commit is contained in:
Jonathan Puckey 2012-11-10 11:20:07 +01:00
commit 30f63599f1

View file

@ -25,59 +25,36 @@ new function() {
// objects, dealing with baseVal, and item lists. // objects, dealing with baseVal, and item lists.
// index is option, and if passed, causes a lookup in a list. // index is option, and if passed, causes a lookup in a list.
function getValue(svg, key, index) { function getValue(svg, key, allowNull, index) {
var base = svg[key].baseVal; var base = svg[key].baseVal,
return index !== undefined value = index !== undefined
? index < base.numberOfItems ? base.getItem(index).value || 0 : 0 ? index < base.numberOfItems ? base.getItem(index).value : null
: base.value || 0; : base.value;
return !allowNull && value == null ? 0 : value;
} }
function getPoint(svg, x, y, index) { function getPoint(svg, x, y, allowNull, index) {
return Point.create(getValue(svg, x, index), getValue(svg, y, index)); x = getValue(svg, x, allowNull, index);
y = getValue(svg, y, allowNull, index);
return x == null && y == null ? null : Point.create(x || 0, y || 0);
} }
function getSize(svg, w, h, index) { function getSize(svg, w, h, allowNull, index) {
return Size.create(getValue(svg, w, index), getValue(svg, h, index)); w = getValue(svg, w, allowNull, index);
h = getValue(svg, h, allowNull, index);
return w == null && h == null ? null : Size.create(w || 0, h || 0);
} }
// Converts a string value to the specified type // Converts a string attribute value to the specified type
function convertStringTo(value, type) { function convertValue(value, type) {
return (value === 'none' return value === 'none'
? null ? null
: type === 'number' : type === 'number'
? parseFloat(value, 10) ? parseFloat(value, 10)
: type === 'array' : type === 'array'
? value.split(/[\s,]+/g).map(parseFloat) ? value.split(/[\s,]+/g).map(parseFloat)
: type === 'color' && getDefinition(value) : type === 'color' && getDefinition(value)
|| value); || value;
}
function getSvgRadius(svg) {
return getValue(svg, 'r');
}
function getSvgOrigin(svg) {
return getPoint(svg, 'x1', 'y1');
}
function getSvgDestination(svg) {
return getPoint(svg, 'x2', 'y2');
}
function getSvgCenter(svg) {
return getPoint(svg, 'cx', 'cy');
}
function getSvgPoint(svg, index) {
return getPoint(svg, 'x', 'y', index);
}
function getSvgRadiusSize(svg) {
return getSize(svg, 'rx', 'ry');
}
function getSvgSize(svg) {
return getSize(svg, 'width', 'height');
} }
// Define importer functions for various SVG node types // Define importer functions for various SVG node types
@ -230,26 +207,20 @@ new function() {
stops = []; stops = [];
for (var i = 0, l = nodes.length; i < l; i++) { for (var i = 0, l = nodes.length; i < l; i++) {
var node = nodes[i]; var node = nodes[i];
if (node.nodeType == 1) { if (node.nodeType == 1)
var stop = new GradientStop(); stops.push(applyAttributes(new GradientStop(), node));
applyAttributes(stop, node);
stops.push(stop);
}
} }
var gradient = new Gradient(stops), var gradient = new Gradient(stops),
isRadial = type == 'radialgradient', isRadial = type == 'radialgradient',
origin, destination, highlight; origin, destination, highlight;
if (isRadial) { if (isRadial) {
gradient.type = 'radial'; gradient.type = 'radial';
origin = getSvgCenter(svg); origin = getPoint(svg, 'cx', 'cy');
destination = origin.add(getSvgRadius(svg), 0); destination = origin.add(getValue(svg, 'r'), 0);
var fx = svg.getAttribute('fx'); highlight = getPoint(svg, 'fx', 'fy', true);
if (fx) {
highlight = getPoint(svg, 'fx', 'fy');
}
} else { } else {
origin = getSvgOrigin(svg); origin = getPoint(svg, 'x1', 'y1');
destination = getSvgDestination(svg); destination = getPoint(svg, 'x2', 'y2');
} }
var gradientColor = new GradientColor(gradient, origin, destination, highlight); var gradientColor = new GradientColor(gradient, origin, destination, highlight);
applyAttributes(gradientColor, svg); applyAttributes(gradientColor, svg);
@ -273,6 +244,10 @@ new function() {
polyline: importPoly, polyline: importPoly,
// http://www.w3.org/TR/SVG/paths.html // http://www.w3.org/TR/SVG/paths.html
path: importPath, path: importPath,
// http://www.w3.org/TR/SVG/pservers.html#LinearGradients
lineargradient: importGradient,
// http://www.w3.org/TR/SVG/pservers.html#RadialGradients
radialgradient: importGradient,
// http://www.w3.org/TR/SVG/struct.html#SymbolElement // http://www.w3.org/TR/SVG/struct.html#SymbolElement
symbol: function(svg, type) { symbol: function(svg, type) {
@ -292,22 +267,23 @@ new function() {
// http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGCircleElement // http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGCircleElement
circle: function(svg) { circle: function(svg) {
return new Path.Circle(getSvgCenter(svg), getSvgRadius(svg)); return new Path.Circle(getPoint(svg, 'cx', 'cy'),
getValue(svg, 'r'));
}, },
// http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGEllipseElement // http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGEllipseElement
ellipse: function(svg) { ellipse: function(svg) {
var center = getSvgCenter(svg), var center = getPoint(svg, 'cx', 'cy'),
radius = getSvgRadiusSize(svg); radius = getSize(svg, 'rx', 'ry');
return new Path.Ellipse(new Rectangle(center.subtract(radius), return new Path.Ellipse(new Rectangle(center.subtract(radius),
center.add(radius))); center.add(radius)));
}, },
// http://www.w3.org/TR/SVG/shapes.html#RectElement // http://www.w3.org/TR/SVG/shapes.html#RectElement
rect: function(svg) { rect: function(svg) {
var point = getSvgPoint(svg), var point = getPoint(svg, 'x', 'y'),
size = getSvgSize(svg), size = getSize(svg, 'width', 'height'),
radius = getSvgRadiusSize(svg); radius = getSize(svg, 'rx', 'ry');
// If radius is 0, Path.RoundRectangle automatically produces a // If radius is 0, Path.RoundRectangle automatically produces a
// normal rectangle for us. // normal rectangle for us.
return new Path.RoundRectangle(new Rectangle(point, size), radius); return new Path.RoundRectangle(new Rectangle(point, size), radius);
@ -315,7 +291,8 @@ new function() {
// http://www.w3.org/TR/SVG/shapes.html#LineElement // http://www.w3.org/TR/SVG/shapes.html#LineElement
line: function(svg) { line: function(svg) {
return new Path.Line(getOrigin(svg), getDestination(svg)); return new Path.Line(getPoint(svg, 'x1', 'y1'),
getPoint(svg, 'x2', 'y2'));
}, },
text: function(svg) { text: function(svg) {
@ -327,13 +304,11 @@ new function() {
// TODO: Support for these is missing in Paper.js right now // TODO: Support for these is missing in Paper.js right now
// rotate: character rotation // rotate: character rotation
// lengthAdjust: // lengthAdjust:
var text = new PointText(getSvgPoint(svg, 0) var text = new PointText(getPoint(svg, 'x', 'y', false, 0)
.add(getPoint(svg, 'dx', 'dy', 0))); .add(getPoint(svg, 'dx', 'dy', false, 0)));
text.content = svg.textContent || ''; text.content = svg.textContent || '';
return text; return text;
}, }
lineargradient: importGradient,
radialgradient: importGradient
}; };
/** /**
@ -370,7 +345,7 @@ new function() {
return item; return item;
var entry = SvgStyles.attributes[name]; var entry = SvgStyles.attributes[name];
if (entry) { if (entry) {
item._style[entry.set](convertStringTo(value, entry.type)); item._style[entry.set](convertValue(value, entry.type));
} else { } else {
switch (name) { switch (name) {
case 'id': case 'id':
@ -421,24 +396,21 @@ new function() {
break; break;
// http://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute // http://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute
case 'offset': case 'offset':
var isPercentage = value[value.length - 1] == '%'; var percentage = value.match(/(.*)%$/);
value = parseFloat(isPercentage ? value.slice(0, -1) : value, 10); item.setRampPoint(percentage ? percentage[1] / 100 : value);
item.setRampPoint(isPercentage ? value / 100 : value);
break; break;
case 'xlink:href': case 'xlink:href':
var definition = definitions[value.substr(1)]; var definition = definitions[value.substring(1)];
// Use place if we're dealing with a symbol: // Use place if we're dealing with a symbol:
item = definition.place ? definition.place() : definition.clone(); item = definition.place ? definition.place() : definition.clone();
break; break;
// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute // http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
case 'viewBox': case 'viewBox':
var values = convertStringTo(value, 'array'), var values = convertValue(value, 'array'),
rectangle = Rectangle.create.apply(this, values); rectangle = Rectangle.create.apply(this, values);
// TODO: how to deal with the svg element? // TODO: how to deal with the svg element?
if (!name == 'svg') if (name !== 'svg')
(item.getDefinition ? item.getDefinition() : item).setBounds(rectangle); (item.getDefinition ? item.getDefinition() : item).setBounds(rectangle);
default:
// Not supported yet.
break; break;
} }
} }