-<!DOCTYPE html><html><head><title>Sencha Documentation Project</title><link rel="stylesheet" href="../reset.css" type="text/css"><link rel="stylesheet" href="../prettify.css" type="text/css"><link rel="stylesheet" href="../prettify_sa.css" type="text/css"><script type="text/javascript" src="../prettify.js"></script></head><body onload="prettyPrint()"><pre class="prettyprint"><pre><span id='Ext-draw.engine.Vml'>/**
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>The source code</title>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+ <style type="text/css">
+ .highlight { display: block; background-color: #ddd; }
+ </style>
+ <script type="text/javascript">
+ function highlight() {
+ document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+ }
+ </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+ <pre class="prettyprint lang-js"><span id='Ext-draw-engine-Vml'>/**
</span> * @class Ext.draw.engine.Vml
* @extends Ext.draw.Surface
* Provides specific methods to draw with VML.
extend: 'Ext.draw.Surface',
- requires: ['Ext.draw.Draw', 'Ext.draw.Color', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.core.Element'],
+ requires: ['Ext.draw.Draw', 'Ext.draw.Color', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.Element'],
/* End Definitions */
coordsize: 1000,
coordorigin: '0 0',
+ // VML uses CSS z-index and therefore doesn't need sprites to be kept in zIndex order
+ orderSpritesByZIndex: false,
+
// @private
// Convert an SVG standard path into a VML path
path2vml: function (path) {
zoom = me.zoom,
vml = sprite.vml || (sprite.vml = {}),
round = Math.round,
- el = (type === 'image') ? me.createNode('image') : me.createNode('shape'),
+ el = me.createNode('shape'),
path, skew, textPath;
el.coordsize = zoom + ' ' + zoom;
// Apply minimum default attributes
Ext.applyIf(scrubbedAttrs, me.minDefaults[sprite.type]);
- if (sprite.type == 'image') {
- Ext.apply(sprite.attr, {
- x: scrubbedAttrs.x,
- y: scrubbedAttrs.y,
- width: scrubbedAttrs.width,
- height: scrubbedAttrs.height
- });
- bbox = sprite.getBBox();
- el.setStyle({
- width: bbox.width + 'px',
- height: bbox.height + 'px'
- });
- dom.src = scrubbedAttrs.src;
- }
-
if (dom.href) {
dom.href = scrubbedAttrs.href;
}
Math.round(cx * me.zoom));
sprite.dirtyPath = false;
}
- else if (sprite.type !== "text" && sprite.type !== 'image') {
+ else if (sprite.type !== "text") {
sprite.attr.path = scrubbedAttrs.path = me.setPaths(sprite, scrubbedAttrs) || scrubbedAttrs.path;
dom.path = me.path2vml(scrubbedAttrs.path);
sprite.dirtyPath = false;
}
// Handle fill and opacity
- if (scrubbedAttrs.opacity || scrubbedAttrs['stroke-opacity'] || scrubbedAttrs.fill) {
+ if (sprite.type == 'image' || scrubbedAttrs.opacity || scrubbedAttrs['fill-opacity'] || scrubbedAttrs.fill) {
me.setFill(sprite, scrubbedAttrs);
}
spriteAttr.ry = params.ry;
return Ext.draw.Draw.ellipsePath(sprite);
}
- else if (sprite.type == 'rect') {
+ else if (sprite.type == 'rect' || sprite.type == 'image') {
spriteAttr.rx = spriteAttr.ry = params.r;
return Ext.draw.Draw.rectPath(sprite);
}
setFill: function(sprite, params) {
var me = this,
- el = sprite.el.dom,
- fillEl = el.fill,
- newfill = false,
+ el = sprite.el,
+ dom = el.dom,
+ fillEl = dom.getElementsByTagName('fill')[0],
opacity, gradient, fillUrl, rotation, angle;
- if (!fillEl) {
- // NOT an expando (but it sure looks like one)...
- fillEl = el.fill = me.createNode("fill");
- newfill = true;
+ if (fillEl) {
+ dom.removeChild(fillEl);
+ } else {
+ fillEl = me.createNode('fill');
}
if (Ext.isArray(params.fill)) {
params.fill = params.fill[0];
}
- if (params.fill == "none") {
+ if (sprite.type == 'image') {
+ fillEl.on = true;
+ fillEl.src = params.src;
+ fillEl.type = "tile";
+ fillEl.rotate = true;
+ } else if (params.fill == "none") {
fillEl.on = false;
- }
- else {
+ } else {
if (typeof params.opacity == "number") {
fillEl.opacity = params.opacity;
}
fillEl.angle = angle;
fillEl.type = "gradient";
fillEl.method = "sigma";
- fillEl.colors.value = gradient.colors;
+ fillEl.colors = gradient.colors;
}
// Otherwise treat it as an image
else {
fillEl.src = fillUrl;
fillEl.type = "tile";
+ fillEl.rotate = true;
}
}
else {
- fillEl.color = Ext.draw.Color.toHex(params.fill);
+ fillEl.color = Ext.draw.Color.toHex(params.fill) || params.fill;
fillEl.src = "";
fillEl.type = "solid";
}
}
}
- if (newfill) {
- el.appendChild(fillEl);
- }
+ dom.appendChild(fillEl);
},
setStroke: function(sprite, params) {
},
setSize: function(width, height) {
- var me = this,
- viewBox = me.viewBox,
- scaleX, scaleY, items, i, len;
+ var me = this;
width = width || me.width;
height = height || me.height;
me.width = width;
me.height = height;
- if (!me.el) {
- return;
- }
+ if (me.el) {
+ // Size outer div
+ if (width != undefined) {
+ me.el.setWidth(width);
+ }
+ if (height != undefined) {
+ me.el.setHeight(height);
+ }
- // Size outer div
- if (width != undefined) {
- me.el.setWidth(width);
- }
- if (height != undefined) {
- me.el.setHeight(height);
+ // Handle viewBox sizing
+ me.applyViewBox();
+
+ me.callParent(arguments);
}
+ },
+
+ setViewBox: function(x, y, width, height) {
+ this.callParent(arguments);
+ this.viewBox = {
+ x: x,
+ y: y,
+ width: width,
+ height: height
+ };
+ this.applyViewBox();
+ },
+
+<span id='Ext-draw-engine-Vml-method-applyViewBox'> /**
+</span> * @private Using the current viewBox property and the surface's width and height, calculate the
+ * appropriate viewBoxShift that will be applied as a persistent transform to all sprites.
+ */
+ applyViewBox: function() {
+ var me = this,
+ viewBox = me.viewBox,
+ width = me.width,
+ height = me.height,
+ viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight,
+ relativeHeight, relativeWidth, size;
- // Handle viewBox sizing
if (viewBox && (width || height)) {
- var viewBoxX = viewBox.x,
- viewBoxY = viewBox.y,
- viewBoxWidth = viewBox.width,
- viewBoxHeight = viewBox.height,
- relativeHeight = height / viewBoxHeight,
- relativeWidth = width / viewBoxWidth,
- size;
+ viewBoxX = viewBox.x;
+ viewBoxY = viewBox.y;
+ viewBoxWidth = viewBox.width;
+ viewBoxHeight = viewBox.height;
+ relativeHeight = height / viewBoxHeight;
+ relativeWidth = width / viewBoxWidth;
+
if (viewBoxWidth * relativeHeight < width) {
viewBoxX -= (width - viewBoxWidth * relativeHeight) / 2 / relativeHeight;
}
if (viewBoxHeight * relativeWidth < height) {
viewBoxY -= (height - viewBoxHeight * relativeWidth) / 2 / relativeWidth;
}
+
size = 1 / Math.max(viewBoxWidth / width, viewBoxHeight / height);
- // Scale and translate group
+
me.viewBoxShift = {
dx: -viewBoxX,
dy: -viewBoxY,
scale: size
};
- items = me.items.items;
- for (i = 0, len = items.length; i < len; i++) {
- me.transform(items[i]);
- }
+ me.items.each(function(item) {
+ me.transform(item);
+ });
}
- this.callParent(arguments);
- },
-
- setViewBox: function(x, y, width, height) {
- this.callParent(arguments);
- this.viewBox = {
- x: x,
- y: y,
- width: width,
- height: height
- };
},
onAdd: function(item) {
this.callParent(arguments);
},
+ // VML Node factory method (createNode)
+ createNode : (function () {
+ try {
+ var doc = Ext.getDoc().dom;
+ if (!doc.namespaces.rvml) {
+ doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
+ }
+ return function (tagName) {
+ return doc.createElement("<rvml:" + tagName + ' class="rvml">');
+ };
+ } catch (e) {
+ return function (tagName) {
+ return doc.createElement("<" + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
+ };
+ }
+ })(),
+
render: function (container) {
var me = this,
doc = Ext.getDoc().dom;
- // VML Node factory method (createNode)
- if (!me.createNode) {
- try {
- if (!doc.namespaces.rvml) {
- doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
- }
- me.createNode = function (tagName) {
- return doc.createElement("<rvml:" + tagName + ' class="rvml">');
- };
- } catch (e) {
- me.createNode = function (tagName) {
- return doc.createElement("<" + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
- };
- }
- }
if (!me.el) {
var el = doc.createElement("div");
};
},
- transform: function(sprite) {
+ extractTransform: function (sprite) {
var me = this,
- matrix = Ext.create('Ext.draw.Matrix'),
- transforms = sprite.transformations,
- transformsLength = transforms.length,
- i = 0,
- deltaDegrees = 0,
- deltaScaleX = 1,
- deltaScaleY = 1,
- flip = "",
- el = sprite.el,
- dom = el.dom,
- domStyle = dom.style,
- zoom = me.zoom,
- skew = sprite.skew,
- deltaX, deltaY, transform, type, compensate, y, fill, newAngle,zoomScaleX, zoomScaleY, newOrigin;
-
- for (; i < transformsLength; i++) {
- transform = transforms[i];
- type = transform.type;
- if (type == "translate") {
- matrix.translate(transform.x, transform.y);
- }
- else if (type == "rotate") {
- matrix.rotate(transform.degrees, transform.x, transform.y);
- deltaDegrees += transform.degrees;
- }
- else if (type == "scale") {
- matrix.scale(transform.x, transform.y, transform.centerX, transform.centerY);
- deltaScaleX *= transform.x;
- deltaScaleY *= transform.y;
- }
+ matrix = Ext.create('Ext.draw.Matrix'), scale,
+ transformstions, tranformationsLength,
+ transform, i = 0,
+ shift = me.viewBoxShift;
+
+ for(transformstions = sprite.transformations, tranformationsLength = transformstions.length;
+ i < tranformationsLength; i ++) {
+ transform = transformstions[i];
+ switch (transform.type) {
+ case 'translate' :
+ matrix.translate(transform.x, transform.y);
+ break;
+ case 'rotate':
+ matrix.rotate(transform.degrees, transform.x, transform.y);
+ break;
+ case 'scale':
+ matrix.scale(transform.x || transform.scale, transform.y || transform.scale, transform.centerX, transform.centerY);
+ break;
+ }
+ }
+
+ if (shift) {
+ matrix.add(1, 0, 0, 1, shift.dx, shift.dy);
+ matrix.prepend(shift.scale, 0, 0, shift.scale, 0, 0);
}
+
+ return sprite.matrix = matrix;
+ },
- if (me.viewBoxShift) {
- matrix.scale(me.viewBoxShift.scale, me.viewBoxShift.scale, -1, -1);
- matrix.add(1, 0, 0, 1, me.viewBoxShift.dx, me.viewBoxShift.dy);
+ setSimpleCoords: function(sprite, sx, sy, dx, dy, rotate) {
+ var me = this,
+ matrix = sprite.matrix,
+ dom = sprite.el.dom,
+ style = dom.style,
+ yFlipper = 1,
+ flip = "",
+ fill = dom.getElementsByTagName('fill')[0],
+ kx = me.zoom / sx,
+ ky = me.zoom / sy,
+ rotationCompensation;
+ if (!sx || !sy) {
+ return;
+ }
+ dom.coordsize = Math.abs(kx) + ' ' + Math.abs(ky);
+ style.rotation = rotate * (sx * sy < 0 ? -1 : 1);
+ if (rotate) {
+ rotationCompensation = me.rotationCompensation(rotate, dx, dy);
+ dx = rotationCompensation.x;
+ dy = rotationCompensation.y;
+ }
+ if (sx < 0) {
+ flip += "x"
}
+ if (sy < 0) {
+ flip += " y";
+ yFlipper = -1;
+ }
+ style.flip = flip;
+ dom.coordorigin = (dx * -kx) + ' ' + (dy * -ky);
+ if (fill) {
+ dom.removeChild(fill);
+ rotationCompensation = me.rotationCompensation(rotate, matrix.x(sprite.x, sprite.y), matrix.y(sprite.x, sprite.y));
+ fill.position = rotationCompensation.x * yFlipper + ' ' + rotationCompensation.y * yFlipper;
+ fill.size = sprite.width * Math.abs(sx) + ' ' + sprite.height * Math.abs(sy);
+ dom.appendChild(fill);
+ }
+ },
- sprite.matrix = matrix;
+ transform : function (sprite) {
+ var me = this,
+ el = sprite.el,
+ skew = sprite.skew,
+ dom = el.dom,
+ domStyle = dom.style,
+ matrix = me.extractTransform(sprite).clone(),
+ split, zoom = me.zoom,
+ fill = dom.getElementsByTagName('fill')[0],
+ isPatt = !String(sprite.fill).indexOf("url("),
+ offset, c;
// Hide element while we transform
- if (sprite.type != "image" && skew) {
+ if (sprite.type != "image" && skew && !isPatt) {
// matrix transform via VML skew
skew.matrix = matrix.toString();
- skew.offset = matrix.offset();
- }
- else {
- deltaX = matrix.matrix[0][2];
- deltaY = matrix.matrix[1][2];
- // Scale via coordsize property
- zoomScaleX = zoom / deltaScaleX;
- zoomScaleY = zoom / deltaScaleY;
-
- dom.coordsize = Math.abs(zoomScaleX) + " " + Math.abs(zoomScaleY);
-
- // Rotate via rotation property
- newAngle = deltaDegrees * (deltaScaleX * ((deltaScaleY < 0) ? -1 : 1));
- if (newAngle != domStyle.rotation && !(newAngle === 0 && !domStyle.rotation)) {
- domStyle.rotation = newAngle;
- }
- if (deltaDegrees) {
- // Compensate x/y position due to rotation
- compensate = me.rotationCompensation(deltaDegrees, deltaX, deltaY);
- deltaX = compensate.x;
- deltaY = compensate.y;
- }
-
- // Handle negative scaling via flipping
- if (deltaScaleX < 0) {
- flip += "x";
- }
- if (deltaScaleY < 0) {
- flip += " y";
- y = -1;
- }
- if (flip != "" && !dom.style.flip) {
- domStyle.flip = flip;
- }
-
- // Translate via coordorigin property
- newOrigin = (deltaX * -zoomScaleX) + " " + (deltaY * -zoomScaleY);
- if (newOrigin != dom.coordorigin) {
- dom.coordorigin = (deltaX * -zoomScaleX) + " " + (deltaY * -zoomScaleY);
+ // skew.offset = '32767,1' OK
+ // skew.offset = '32768,1' Crash
+ // M$, R U kidding??
+ offset = matrix.offset();
+ if (offset[0] > 32767) {
+ offset[0] = 32767;
+ } else if (offset[0] < -32768) {
+ offset[0] = -32768
+ }
+ if (offset[1] > 32767) {
+ offset[1] = 32767;
+ } else if (offset[1] < -32768) {
+ offset[1] = -32768
+ }
+ skew.offset = offset;
+ } else {
+ if (skew) {
+ skew.matrix = "1 0 0 1";
+ skew.offset = "0 0";
+ }
+ split = matrix.split();
+ if (split.isSimple) {
+ domStyle.filter = '';
+ me.setSimpleCoords(sprite, split.scaleX, split.scaleY, split.translateX, split.translateY, split.rotate / Math.PI * 180);
+ } else {
+ domStyle.filter = matrix.toFilter();
+ var bb = me.getBBox(sprite),
+ dx = bb.x - sprite.x,
+ dy = bb.y - sprite.y;
+ dom.coordorigin = (dx * -zoom) + ' ' + (dy * -zoom);
+ if (fill) {
+ dom.removeChild(fill);
+ fill.position = dx + ' ' + dy;
+ fill.size = sprite.width * sprite.scale.x + ' ' + sprite.height * 1.1;
+ dom.appendChild(fill);
+ }
}
}
},
}
},
-<span id='Ext-draw.engine.Vml-method-addGradient'> /**
+<span id='Ext-draw-engine-Vml-method-addGradient'> /**
</span> * Adds a definition to this Surface for a linear gradient. We convert the gradient definition
* to its corresponding VML attributes and store it for later use by individual sprites.
* @param {Object} gradient
delete me.el;
}
});
-</pre></pre></body></html>
\ No newline at end of file
+</pre>
+</body>
+</html>