зеркало из https://github.com/mozilla/shumway.git
Merge gfx work.
This commit is contained in:
Родитель
cc1826b664
Коммит
268b957a09
2162
lib/Kanvas/kanvas.js
2162
lib/Kanvas/kanvas.js
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -94,8 +94,6 @@ var DisplayObjectDefinition = (function () {
|
|||
TRACE_SYMBOLS_INFO && this._updateTraceSymbolInfo();
|
||||
|
||||
this._updateCurrentTransform();
|
||||
|
||||
this._accessibilityProperties = null;
|
||||
},
|
||||
|
||||
_updateTraceSymbolInfo: function () {
|
||||
|
@ -154,43 +152,26 @@ var DisplayObjectDefinition = (function () {
|
|||
pt.x /= scale;
|
||||
pt.y /= scale;
|
||||
}
|
||||
|
||||
var hitCtx = this._graphics._hitCtx;
|
||||
|
||||
if (hitCtx.isPointInPath(pt.x, pt.y))
|
||||
return true;
|
||||
var bbox = this._bbox;
|
||||
if (bbox) {
|
||||
pt.x += bbox.left;
|
||||
pt.y += bbox.top;
|
||||
}
|
||||
|
||||
var subpaths = this._graphics._subpaths;
|
||||
for (var i = 0, n = subpaths.length; i < n; i++) {
|
||||
var pathTracker = subpaths[i];
|
||||
var path = pathTracker.target;
|
||||
var path = subpaths[i];
|
||||
|
||||
if (!path.strokeStyle)
|
||||
continue;
|
||||
if (path.isPointInPath(pt.x, pt.y))
|
||||
return true;
|
||||
|
||||
var drawingStyles = pathTracker.drawingStyles;
|
||||
if (hitCtx.mozIsPointInStroke) {
|
||||
hitCtx.strokeStyle = path.strokeStyle;
|
||||
for (var prop in drawingStyles)
|
||||
hitCtx[prop] = drawingStyles[prop];
|
||||
|
||||
if (hitCtx.mozIsPointInStroke(pt.x, pt.y))
|
||||
return true;
|
||||
} else {
|
||||
var strokeHitCtx = path._strokeHitContext;
|
||||
if (!strokeHitCtx) {
|
||||
var strokeHitCanvas = hitCtx.canvas.cloneNode();
|
||||
strokeHitCtx = strokeHitCanvas.getContext('2d');
|
||||
path._strokeHitContext = strokeHitCtx;
|
||||
pathTracker.strokeToPath(strokeHitCtx, {
|
||||
strokeWidth: drawingStyles.lineWidth,
|
||||
startCap: drawingStyles.lineCap,
|
||||
endCap: drawingStyles.lineCap,
|
||||
join: drawingStyles.lineJoin,
|
||||
miterLimit: drawingStyles.miterLimit
|
||||
});
|
||||
if (path.strokeStyle) {
|
||||
var strokePath = path._strokePath;
|
||||
if (!strokePath) {
|
||||
strokePath = path.strokePath(path.drawingStyles);
|
||||
path._strokePath = strokePath;
|
||||
}
|
||||
if (strokeHitCtx.isPointInPath(pt.x, pt.y))
|
||||
if (strokePath.isPointInPath(pt.x, pt.y))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -274,12 +255,10 @@ var DisplayObjectDefinition = (function () {
|
|||
},
|
||||
|
||||
get accessibilityProperties() {
|
||||
somewhatImplemented("accessibilityProperties");
|
||||
return this._accessibilityProperties;
|
||||
return null;
|
||||
},
|
||||
set accessibilityProperties(val) {
|
||||
somewhatImplemented("accessibilityProperties");
|
||||
this._accessibilityProperties = val;
|
||||
notImplemented();
|
||||
},
|
||||
get alpha() {
|
||||
return this._alpha;
|
||||
|
|
|
@ -25,142 +25,22 @@ var GraphicsDefinition = (function () {
|
|||
this._bitmap = null;
|
||||
this._drawingStyles = null;
|
||||
this._fillStyle = null;
|
||||
this._fillTransform = null;
|
||||
this._mx = null;
|
||||
this._my = null;
|
||||
this._revision = 0;
|
||||
this._scale = 1;
|
||||
this._strokeStyle = null;
|
||||
this._subpaths = [];
|
||||
|
||||
var hitCanvas = document.createElement('canvas');
|
||||
hitCanvas.width = hitCanvas.height = 1;
|
||||
this._hitCtx = hitCanvas.getContext('2d');
|
||||
},
|
||||
|
||||
_beginFillObject: function (fill) {
|
||||
if (fill === null) {
|
||||
this.endFill();
|
||||
} else {
|
||||
switch (fill.__class__) {
|
||||
case 'flash.display.GraphicsEndFill':
|
||||
this.endFill();
|
||||
break;
|
||||
case 'flash.display.GraphicsSolidFill':
|
||||
this.beginFill(fill.color, fill.alpha);
|
||||
break;
|
||||
case 'flash.display.GraphicsGradientFill':
|
||||
this.beginGradientFill(
|
||||
fill.type,
|
||||
fill.colors,
|
||||
fill.alphas,
|
||||
fill.ratios,
|
||||
fill.matrix,
|
||||
fill.spreadMethod,
|
||||
fill.interpolationMethod,
|
||||
fill.focalPointRatio
|
||||
);
|
||||
break;
|
||||
case 'flash.display.GraphicsBitmapFill':
|
||||
this.beginBitmapFill(fill.bitmapData, fill.matrix, fill.repeat, fill.smooth);
|
||||
break;
|
||||
case 'flash.display.GraphicsShaderFill':
|
||||
this.beginShaderFill(fill.shader, fill.matrix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_createLinearGradient: function (x0, y0, x1, y1) {
|
||||
return fillContext.createLinearGradient(x0, y0, x1, y1);
|
||||
},
|
||||
_beginStrokeObject: function (istroke) {
|
||||
var stroke = null;
|
||||
var fill = null;
|
||||
|
||||
if (istroke !== null && istroke.__class__ === 'flash.display.GraphicsStroke')
|
||||
stroke = istroke;
|
||||
if (stroke && stroke.fill && stroke.fill.__isIGraphicsFill__)
|
||||
fill = stroke.fill;
|
||||
|
||||
if (stroke === null || fill === null) {
|
||||
this.lineStyle(null);
|
||||
} else if (fill.__class__ === 'flash.display.GraphicsSolidFill') {
|
||||
this.lineStyle(
|
||||
stroke.thickness,
|
||||
fill.color,
|
||||
fill.alpha,
|
||||
stroke.pixelHinting,
|
||||
stroke.scaleMode,
|
||||
stroke.caps,
|
||||
stroke.joints,
|
||||
stroke.miterLimit
|
||||
);
|
||||
} else {
|
||||
this.lineStyle(
|
||||
stroke.thickness,
|
||||
0,
|
||||
1,
|
||||
stroke.pixelHinting,
|
||||
stroke.scaleMode,
|
||||
stroke.caps,
|
||||
stroke.joints,
|
||||
stroke.miterLimit
|
||||
);
|
||||
|
||||
switch (fill.__class__) {
|
||||
case 'flash.display.GraphicsGradientFill':
|
||||
this.lineGradientStyle(
|
||||
fill.type,
|
||||
fill.colors,
|
||||
fill.alphas,
|
||||
fill.ratios,
|
||||
fill.matrix,
|
||||
fill.spreadMethod,
|
||||
fill.interpolationMethod,
|
||||
fill.focalPointRatio
|
||||
);
|
||||
break;
|
||||
case 'flash.display.GraphicsBitmapFill':
|
||||
this.lineBitmapStyle(fill.bitmapData, fill.matrix, fill.repeat, fill.smooth);
|
||||
break;
|
||||
case 'flash.display.GraphicsShaderFill':
|
||||
this.lineShaderStyle(fill.shader, fill.matrix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_createRadialGradient: function (x0, y0, r0, x1, y1, r1) {
|
||||
return fillContext.createRadialGradient(x0, y0, r0, x1, y1, r1);
|
||||
},
|
||||
_cacheAsBitmap: function (bbox) {
|
||||
var bounds = this._getBounds();
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = bounds.width;
|
||||
canvas.height = bounds.height;
|
||||
var ctx = canvas.getContext('kanvas-2d');
|
||||
ctx.translate(-bbox.left, -bbox.top);
|
||||
var scale = this._scale;
|
||||
if (scale !== 1)
|
||||
ctx.scale(scale, scale);
|
||||
var subpaths = this._subpaths;
|
||||
for (var i = 0; i < subpaths.length; i++) {
|
||||
var pathTracker = subpaths[i];
|
||||
var path = pathTracker.target;
|
||||
if (path.fillStyle) {
|
||||
ctx.fillStyle = path.fillStyle;
|
||||
if (path.fillTransform) {
|
||||
var m = path.fillTransform;
|
||||
ctx.beginPath();
|
||||
ctx.__draw__(path);
|
||||
ctx.save();
|
||||
ctx.transform(m.a, m.b, m.c, m.d, m.tx, m.ty);
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
} else {
|
||||
ctx.fill(path);
|
||||
}
|
||||
}
|
||||
if (path.strokeStyle) {
|
||||
ctx.strokeStyle = path.strokeStyle;
|
||||
var drawingStyles = pathTracker.drawingStyles;
|
||||
for (var prop in drawingStyles)
|
||||
ctx[prop] = drawingStyles[prop];
|
||||
ctx.stroke(path);
|
||||
}
|
||||
}
|
||||
this._bitmap = canvas;
|
||||
_createPattern: function(image, repetition) {
|
||||
return fillContext.createPattern(image, repetition);
|
||||
},
|
||||
_drawPathObject: function (path) {
|
||||
if (path.__class__ === 'flash.display.GraphicsPath')
|
||||
|
@ -171,15 +51,17 @@ var GraphicsDefinition = (function () {
|
|||
|
||||
get _currentPath() {
|
||||
var path = new Kanvas.Path;
|
||||
var pathTracker = new PolygonTracker(path, this._hitCtx);
|
||||
pathTracker.drawingStyles = this._drawingStyles;
|
||||
if (this._mx !== null || this._my !== null) {
|
||||
path.moveTo(this._mx, this._my);
|
||||
this._mx = this._my = null;
|
||||
}
|
||||
path.drawingStyles = this._drawingStyles;
|
||||
path.fillStyle = this._fillStyle;
|
||||
path.fillTransform = this._fillTransform;
|
||||
path.strokeStyle = this._strokeStyle;
|
||||
this._subpaths.push(pathTracker);
|
||||
this._subpaths.push(path);
|
||||
// Cache as an own property.
|
||||
Object.defineProperty(this, '_currentPath', describeProperty(pathTracker));
|
||||
return pathTracker;
|
||||
Object.defineProperty(this, '_currentPath', describeProperty(path));
|
||||
return path;
|
||||
},
|
||||
|
||||
beginFill: function (color, alpha) {
|
||||
|
@ -189,14 +71,13 @@ var GraphicsDefinition = (function () {
|
|||
delete this._currentPath;
|
||||
|
||||
this._fillStyle = alpha ? toRgba(color, alpha) : null;
|
||||
this._fillTransform = null;
|
||||
},
|
||||
beginGradientFill: function (type, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPos) {
|
||||
var gradient;
|
||||
if (type === 'linear')
|
||||
gradient = fillContext.createLinearGradient(-1, 0, 1, 0);
|
||||
gradient = this._createLinearGradient(-1, 0, 1, 0);
|
||||
else if (type == 'radial')
|
||||
gradient = fillContext.createRadialGradient((focalPos || 0), 0, 0, 0, 0, 1);
|
||||
gradient = this._createRadialGradient((focalPos || 0), 0, 0, 0, 0, 1);
|
||||
else
|
||||
throw ArgumentError();
|
||||
|
||||
|
@ -207,29 +88,27 @@ var GraphicsDefinition = (function () {
|
|||
|
||||
// NOTE firefox really sensitive to really small scale when painting gradients
|
||||
var scale = 819.2;
|
||||
this._fillTransform = matrix ?
|
||||
{ a: scale * matrix.a, b: scale * matrix.b, c: scale * matrix.c, d: scale * matrix.d, tx: matrix.tx, ty: matrix.ty } :
|
||||
{ a: scale, b: 0, c: 0, d: scale, tx: 0, ty: 0 };
|
||||
gradient.currentTransform = matrix ?
|
||||
{ a: scale * matrix.a, b: scale * matrix.b, c: scale * matrix.c, d: scale * matrix.d, e: matrix.tx, f: matrix.ty } :
|
||||
{ a: scale, b: 0, c: 0, d: scale, e: 0, f: 0 };
|
||||
},
|
||||
beginBitmapFill: function (bitmap, matrix, repeat, smooth) {
|
||||
var repeatStyle = repeat ? 'repeat' : 'no-repeat';
|
||||
this._fillStyle = fillContext.createPattern(bitmap._drawable, repeatStyle);
|
||||
var pattern = this._createPattern(bitmap._drawable, repeatStyle);
|
||||
|
||||
var scale = this._scale;
|
||||
this._fillTransform = matrix ?
|
||||
{ a: scale * matrix.a, b: scale * matrix.b, c: scale * matrix.c, d: scale * matrix.d, tx: matrix.tx, ty: matrix.ty } :
|
||||
{ a: scale, b: 0, c: 0, d: scale, tx: 0, ty: 0 };
|
||||
this._fillStyle = pattern;
|
||||
|
||||
pattern.currentTransform = matrix ?
|
||||
{ a: matrix.a, b: matrix.b, c: matrix.c, d: matrix.d, e: matrix.tx, f: matrix.ty } :
|
||||
{ a: scale, b: 0, c: 0, d: scale, e: 0, f: 0 };
|
||||
},
|
||||
clear: function () {
|
||||
delete this._currentPath;
|
||||
|
||||
this._drawingStyles = null;
|
||||
this._fillStyle = null;
|
||||
this._fillTransform = null;
|
||||
this._strokeStyle = null;
|
||||
this._subpaths.length = 0;
|
||||
|
||||
this._hitCtx.beginPath();
|
||||
this._subpaths = [];
|
||||
},
|
||||
copyFrom: function (sourceGraphics) {
|
||||
notImplemented();
|
||||
|
@ -242,16 +121,13 @@ var GraphicsDefinition = (function () {
|
|||
this._currentPath.quadraticCurveTo(cpx, cpy, x, y);
|
||||
this._revision++;
|
||||
},
|
||||
drawGraphicsData: function (graphicsData) {
|
||||
for (var i = 0, n = graphicsData.length; i < n; i++) {
|
||||
var item = graphicsData[i];
|
||||
if (item.__isIGraphicsPath__)
|
||||
this._drawPathObject(item);
|
||||
else if (item.__isIGraphicsFill__)
|
||||
this._beginFillObject(item);
|
||||
else if (item.__isIGraphicsStroke__)
|
||||
this._beginStrokeObject(item);
|
||||
}
|
||||
drawCircle: function (x, y, radius) {
|
||||
this._currentPath.arc(x, y, radius, 0, Math.PI * 2);
|
||||
this._revision++;
|
||||
},
|
||||
drawEllipse: function (x, y, width, height) {
|
||||
this._currentPath.ellipse(x, y, width / 2, height / 2, 0, 0, Math.PI * 2);
|
||||
this._revision++;
|
||||
},
|
||||
drawPath: function (commands, data, winding) {
|
||||
delete this._currentPath;
|
||||
|
@ -292,6 +168,16 @@ var GraphicsDefinition = (function () {
|
|||
var radiusW = ellipseWidth / 2;
|
||||
var radiusH = ellipseHeight / 2;
|
||||
|
||||
this._currentPath.moveTo(x+w, y+h-radiusH);
|
||||
|
||||
if (w === ellipseWidth && h === ellipseHeight) {
|
||||
if (ellipseWidth === ellipseHeight)
|
||||
this._currentPath.arc(x+radiusW, y+radiusH, radiusW, 0, Math.PI * 2);
|
||||
else
|
||||
this._currentPath.ellipse(x+radiusW, y+radiusH, radiusW, radiusH, 0, 0, Math.PI * 2);
|
||||
return;
|
||||
}
|
||||
|
||||
// A-----B
|
||||
// H C
|
||||
// G D
|
||||
|
@ -301,7 +187,6 @@ var GraphicsDefinition = (function () {
|
|||
// tha the Flash player starts and stops the pen
|
||||
// at 'D', so we will too.
|
||||
|
||||
this._currentPath.moveTo(x+w, y+h-radiusH);
|
||||
this._currentPath.arcTo(x+w, y+h, x+w-radiusW, y+h, radiusW, radiusH);
|
||||
this._currentPath.arcTo(x, y+h, x, y+h-radiusH, radiusW, radiusH);
|
||||
this._currentPath.arcTo(x, y, x+radiusW, y, radiusW, radiusH);
|
||||
|
@ -324,7 +209,6 @@ var GraphicsDefinition = (function () {
|
|||
delete this._currentPath;
|
||||
|
||||
this._fillStyle = null;
|
||||
this._fillTransform = null;
|
||||
},
|
||||
lineBitmapStyle: function (bitmap, matrix, repeat, smooth) {
|
||||
notImplemented();
|
||||
|
@ -359,33 +243,24 @@ var GraphicsDefinition = (function () {
|
|||
this._revision++;
|
||||
},
|
||||
moveTo: function (x, y) {
|
||||
this._currentPath.moveTo(x, y);
|
||||
this._revision++;
|
||||
this._mx = x;
|
||||
this._my = y;
|
||||
},
|
||||
_getBounds: function (includeStroke) {
|
||||
var subpaths = this._subpaths;
|
||||
var xMins = [], yMins = [], xMaxs = [], yMaxs = [];
|
||||
for (var i = 0, n = subpaths.length; i < n; i++) {
|
||||
var pathTracker = subpaths[i];
|
||||
var b = pathTracker.getBounds();
|
||||
var path = subpaths[i];
|
||||
var b = path.getBounds();
|
||||
if (b) {
|
||||
xMins.push(b.minX); yMins.push(b.minY); xMaxs.push(b.maxX); yMaxs.push(b.maxY);
|
||||
}
|
||||
if (includeStroke && pathTracker.target.strokeStyle) {
|
||||
var strokeTracker = new PolygonTracker();
|
||||
var drawingStyles = pathTracker.drawingStyles;
|
||||
pathTracker.strokeToPath(strokeTracker, {
|
||||
strokeWidth: drawingStyles.lineWidth,
|
||||
startCap: drawingStyles.lineCap,
|
||||
endCap: drawingStyles.lineCap,
|
||||
join: drawingStyles.lineJoin,
|
||||
miterLimit: drawingStyles.miterLimit
|
||||
});
|
||||
var b = strokeTracker.getBounds();
|
||||
if (b) {
|
||||
xMins.push(b.minX); yMins.push(b.minY); xMaxs.push(b.maxX); yMaxs.push(b.maxY);
|
||||
if (includeStroke && path.strokeStyle) {
|
||||
var lh = path.drawingStyles.lineWidth / 2;
|
||||
xMins.push(b.x - lh); yMins.push(b.y - lh); xMaxs.push(b.x + b.width + lh); yMaxs.push(b.y + b.height + lh);
|
||||
} else {
|
||||
xMins.push(b.x); yMins.push(b.y); xMaxs.push(b.x + b.width); yMaxs.push(b.y + b.height);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (xMins.length === 0) {
|
||||
return 0;
|
||||
|
@ -399,421 +274,6 @@ var GraphicsDefinition = (function () {
|
|||
}
|
||||
};
|
||||
|
||||
var PolygonTracker = (function PolygonTrackerClosure() {
|
||||
var CURVE_APPROX_POINTS = 8;
|
||||
var CIRCLE_APPROX_POINTS = 12; // per PI
|
||||
var CIRCLE_APPROX_SIN = Math.sin(Math.PI / CIRCLE_APPROX_POINTS);
|
||||
var CIRCLE_APPROX_COS = Math.cos(Math.PI / CIRCLE_APPROX_POINTS);
|
||||
function strokeToPath(tracker, options, output) {
|
||||
function buildCap(lines, capStyle, line1, line2) {
|
||||
line1.type = 3;
|
||||
switch (capStyle) {
|
||||
case 'round':
|
||||
var cx = (line1.x2 + line2.x1) / 2;
|
||||
var cy = (line1.y2 + line2.y1) / 2;
|
||||
var dx = (line1.x2 - cx), dy = (line1.y2 - cy);
|
||||
for (var i = 0; i < CIRCLE_APPROX_POINTS; i++) {
|
||||
var dx1 = dx * CIRCLE_APPROX_COS - dy * CIRCLE_APPROX_SIN;
|
||||
var dy1 = dx * CIRCLE_APPROX_SIN + dy * CIRCLE_APPROX_COS;
|
||||
lines.push({
|
||||
x1: cx + dx, y1: cy + dy,
|
||||
x2: cx + dx1, y2: cy + dy1,
|
||||
type: 3});
|
||||
dx = dx1; dy = dy1;
|
||||
}
|
||||
break;
|
||||
case 'square':
|
||||
var capHeight = options.strokeWidth / 2;
|
||||
var dx = line1.x2 - line1.x1, dy = line1.y2 - line1.y1;
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
line1.x2 += dx * capHeight / d;
|
||||
line1.y2 += dy * capHeight / d;
|
||||
line2.x1 += dx * capHeight / d;
|
||||
line2.y1 += dy * capHeight / d;
|
||||
// fall throw
|
||||
case 'none':
|
||||
default:
|
||||
lines.push({
|
||||
x1: line1.x2, y1: line1.y2,
|
||||
x2: line2.x1, y2: line2.y1,
|
||||
type: 3});
|
||||
break;
|
||||
}
|
||||
}
|
||||
function joinLines(cmds, line1, line2, type) {
|
||||
// (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1) = 0, a*x + b*y = c
|
||||
var a1 = (line1.y2 - line1.y1), b1 = -(line1.x2 - line1.x1), c1 = line1.x1 * line1.y2 - line1.x2 * line1.y1;
|
||||
var a2 = (line2.y2 - line2.y1), b2 = -(line2.x2 - line2.x1), c2 = line2.x1 * line2.y2 - line2.x2 * line2.y1;
|
||||
var d = a1 * b2 - b1 * a2;
|
||||
if (d == 0) {
|
||||
// parellel lines doing bevel
|
||||
cmds.push({type: 'lineTo', args: [line1.x2, line1.y2]});
|
||||
cmds.push({type: 'lineTo', args: [line2.x1, line2.y1]});
|
||||
return;
|
||||
}
|
||||
var x = (c1 * b2 - b1 * c2) / d;
|
||||
var y = (a1 * c2 - c1 * a2) / d;
|
||||
var onLine1 = !(
|
||||
(x < line1.x1 && x < line1.x2) || (x > line1.x1 && x > line1.x2) ||
|
||||
(y < line1.y1 && y < line1.y2) || (y > line1.y1 && y > line1.y2));
|
||||
var onLine2 = !(
|
||||
(x < line2.x1 && x < line2.x2) || (x > line2.x1 && x > line2.x2) ||
|
||||
(y < line2.y1 && y < line2.y2) || (y > line2.y1 && y > line2.y2));
|
||||
if (!onLine1 && !onLine2) {
|
||||
switch (type) {
|
||||
default:
|
||||
case 'bevel':
|
||||
cmds.push({type: 'lineTo', args: [line1.x2, line1.y2]});
|
||||
cmds.push({type: 'lineTo', args: [line2.x1, line2.y1]});
|
||||
break;
|
||||
case 'round':
|
||||
cmds.push({type: 'lineTo', args: [line1.x2, line1.y2]});
|
||||
cmds.push({type: 'quadraticCurveTo', args: [x, y, line2.x1, line2.y1]});
|
||||
break;
|
||||
case 'miter':
|
||||
cmds.push({type: 'lineTo', args: [line1.x2, line1.y2]});
|
||||
var a = -(line1.y2 - line2.y1), b = line1.x2 - line2.x1;
|
||||
var d = Math.sqrt(a * a + b * b);
|
||||
var miterLength = (a * (x - line2.x1) + b * (y - line2.y1)) / d;
|
||||
var maxAllowedLength = options.miterLimit * options.strokeWidth / 2;
|
||||
if (miterLength > maxAllowedLength) {
|
||||
var p2 = maxAllowedLength / miterLength, p1 = 1 - p2;
|
||||
cmds.push({type: 'lineTo', args: [line1.x2 * p1 + x * p2, line1.y2 * p1 + y * p2]});
|
||||
cmds.push({type: 'lineTo', args: [line2.x1 * p1 + x * p2, line2.y1 * p1 + y * p2]});
|
||||
} else {
|
||||
cmds.push({type: 'lineTo', args: [x, y]});
|
||||
}
|
||||
cmds.push({type: 'lineTo', args: [line2.x1, line2.y1]});
|
||||
break;
|
||||
}
|
||||
} else if (!onLine1 || !onLine2) {
|
||||
cmds.push({type: 'lineTo', args: onLine1 ? [x, y] : [line1.x2, line1.y2]});
|
||||
cmds.push({type: 'lineTo', args: onLine2 ? [x, y] : [line2.x1, line2.y1]});
|
||||
} else {
|
||||
cmds.push({type: 'lineTo', args: [x, y]});
|
||||
}
|
||||
}
|
||||
function buildPath(lines) {
|
||||
var moveCmd = {type: 'moveTo', args: null};
|
||||
var cmds = [moveCmd];
|
||||
var joinType = options.join;
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
var type = lines[j].type;
|
||||
switch (type) {
|
||||
default:
|
||||
joinLines(cmds, lines[j], lines[(j + 1) % lines.length], joinType);
|
||||
break;
|
||||
case 3: // simple line
|
||||
cmds.push({type: 'lineTo', args: [lines[j].x2, lines[j].y2]});
|
||||
break;
|
||||
case 4: // curve segment connector
|
||||
joinLines(cmds, lines[j], lines[(j + 1) % lines.length], 'bevel');
|
||||
break;
|
||||
}
|
||||
}
|
||||
moveCmd.args = cmds[cmds.length - 1].args.slice(-2);
|
||||
cmds.push({type: 'closePath'});
|
||||
for (var i = 0; i < cmds.length; i++) {
|
||||
output[cmds[i].type].apply(output, cmds[i].args);
|
||||
}
|
||||
}
|
||||
var i = 0;
|
||||
var segments = tracker.segments;
|
||||
var points = tracker.points;
|
||||
var start = segments[0];
|
||||
do {
|
||||
++i;
|
||||
var end = i < segments.length ? segments[i] : points.length;
|
||||
if (points[start].type !== 0) {
|
||||
throw 'invalid points structure';
|
||||
}
|
||||
if (start + 1 >= end) {
|
||||
// only moveTo operation
|
||||
end = start;
|
||||
continue;
|
||||
}
|
||||
var pathClosed = points[end - 1].type === 2;
|
||||
var lastX = points[start].x;
|
||||
var lastY = points[start].y;
|
||||
var lastType = 0;
|
||||
start++;
|
||||
// building paths
|
||||
var forward = [], backward = [];
|
||||
var strokeHalfWidth = options.strokeWidth / 2;
|
||||
for (var j = start; j < end; j++) {
|
||||
var x = points[j].x, y = points[j].y, type = points[j].type;
|
||||
var dx = x - lastX;
|
||||
var dy = y - lastY;
|
||||
if (dx == 0 && dy == 0) continue;
|
||||
var k = strokeHalfWidth / Math.sqrt(dx * dx + dy * dy);
|
||||
dx *= k; dy *= k;
|
||||
forward.push({
|
||||
x1: lastX + dy, y1: lastY - dx,
|
||||
x2: x + dy, y2: y - dx,
|
||||
type: type
|
||||
});
|
||||
backward.push({
|
||||
x1: x - dy, y1: y + dx,
|
||||
x2: lastX - dy, y2: lastY + dx,
|
||||
type: lastType
|
||||
});
|
||||
lastX = x; lastY = y; lastType = type;
|
||||
}
|
||||
if (forward.length === 0) {
|
||||
// no segments are created, skipping the stroke
|
||||
start = end;
|
||||
continue;
|
||||
}
|
||||
|
||||
backward.reverse();
|
||||
if (!pathClosed) {
|
||||
buildCap(forward, options.endCap, forward[forward.length - 1], backward[0]);
|
||||
buildCap(backward, options.startCap, backward[backward.length - 1], forward[0]);
|
||||
forward = forward.concat(backward);
|
||||
buildPath(forward);
|
||||
} else {
|
||||
buildPath(forward);
|
||||
buildPath(backward);
|
||||
}
|
||||
start = end;
|
||||
} while (i < segments.length);
|
||||
}
|
||||
|
||||
function pushCurveApprox(points, x1, y1, x2, y2) {
|
||||
var x0 = points[points.length - 1].x;
|
||||
var y0 = points[points.length - 1].y;
|
||||
for (var i = 0; i < CURVE_APPROX_POINTS; i++) {
|
||||
var p2 = (i + 1) / CURVE_APPROX_POINTS, p1 = 1 - p2;
|
||||
var x01 = x0 * p1 + x1 * p2, y01 = y0 * p1 + y1 * p2;
|
||||
var x12 = x1 * p1 + x2 * p2, y12 = y1 * p1 + y2 * p2;
|
||||
var x = x01 * p1 + x12 * p2, y = y01 * p1 + y12 * p2;
|
||||
points.push({x: x, y: y, type: 4});
|
||||
}
|
||||
points[points.length - 1].type = 1;
|
||||
}
|
||||
function pushBezierCurveApprox(points, x1, y1, x2, y2, x3, y3) {
|
||||
var x0 = points[points.length - 1].x;
|
||||
var y0 = points[points.length - 1].y;
|
||||
for (var i = 0; i < CURVE_APPROX_POINTS; i++) {
|
||||
var p2 = (i + 1) / CURVE_APPROX_POINTS, p1 = 1 - p2;
|
||||
var x01 = x0 * p1 + x1 * p2, y01 = y0 * p1 + y1 * p2;
|
||||
var x12 = x1 * p1 + x2 * p2, y12 = y1 * p1 + y2 * p2;
|
||||
var x23 = x2 * p1 + x3 * p2, y23 = y2 * p1 + y3 * p2;
|
||||
var x012 = x01 * p1 + x12 * p2, y012 = y01 * p1 + y12 * p2;
|
||||
var x123 = x12 * p1 + x23 * p2, y123 = y12 * p1 + y23 * p2;
|
||||
var x = x012 * p1 + x123 * p2, y = y012 * p1 + y123 * p2;
|
||||
points.push({x: x, y: y, type: 4});
|
||||
}
|
||||
points[points.length - 1].type = 1;
|
||||
}
|
||||
function normalizeAngle(angle) {
|
||||
while (angle > Math.PI)
|
||||
angle -= 2 * Math.PI;
|
||||
while (angle <= -Math.PI)
|
||||
angle += 2 * Math.PI;
|
||||
return angle;
|
||||
}
|
||||
function pushArcApprox(points, x1, y1, x2, y2, radiusX, radiusY, rotation) {
|
||||
var x0 = points[points.length - 1].x;
|
||||
var y0 = points[points.length - 1].y;
|
||||
var dx01 = x1 - x0, dy01 = y1 - y0, dx12 = x2 - x1, dy12 = y2 - y1;
|
||||
var winding = dx01 * dy12 - dy01 * dx12;
|
||||
// if radiusX or radiusY == 0, or points #0, #1, and #2 are on one line,
|
||||
// just draw simple line to point #1
|
||||
if (radiusX <= 0 || radiusY <= 0 || winding == 0) {
|
||||
points.push({x: x1, y: y1, type: 1});
|
||||
return;
|
||||
}
|
||||
var rotationCos = 1, rotationSin = 0;
|
||||
if (rotation) {
|
||||
rotationCos = Math.cos(rotation);
|
||||
rotationSin = Math.sin(rotation);
|
||||
}
|
||||
// placing major axis to x
|
||||
var dx01_ = dx01 * rotationCos + dy01 * rotationSin;
|
||||
var dy01_ = -dx01 * rotationSin + dy01 * rotationCos;
|
||||
var dx12_ = dx12 * rotationCos + dy12 * rotationSin;
|
||||
var dy12_ = -dx12 * rotationSin + dy12 * rotationCos;
|
||||
var alpha1 = Math.atan2(-dx01_ * radiusY, dy01_ * radiusX);
|
||||
var alpha2 = Math.atan2(-dx12_ * radiusY, dy12_ * radiusX);
|
||||
if (winding < 0) {
|
||||
alpha1 = (alpha1 >= 0 ? -Math.PI : Math.PI) + alpha1;
|
||||
alpha2 = (alpha2 >= 0 ? -Math.PI : Math.PI) + alpha2;
|
||||
}
|
||||
|
||||
// start and end offsets of the arc from center
|
||||
var bx1_ = radiusX * Math.cos(alpha1), by1_ = radiusY * Math.sin(alpha1);
|
||||
var bx2_ = radiusX * Math.cos(alpha2), by2_ = radiusY * Math.sin(alpha2);
|
||||
var bx1 = bx1_ * rotationCos - by1_ * rotationSin;
|
||||
var by1 = bx1_ * rotationSin + by1_ * rotationCos;
|
||||
var bx2 = bx2_ * rotationCos - by2_ * rotationSin;
|
||||
var by2 = bx2_ * rotationSin + by2_ * rotationCos;
|
||||
|
||||
// finding center
|
||||
// (x1 - bx1 - cx) * (y1 - y0) - (y1 - by1 - cy) * (x1 - x0) = 0
|
||||
var a1 = y1 - y0, b1 = -(x1 - x0), c1 = (x1 - bx1) * (y1 - y0) - (y1 - by1) * (x1 - x0);
|
||||
var a2 = y2 - y1, b2 = -(x2 - x1), c2 = (x2 - bx2) * (y2 - y1) - (y2 - by2) * (x2 - x1);
|
||||
var d = a1 * b2 - b1 * a2;
|
||||
var cx = (c1 * b2 - b1 * c2) / d;
|
||||
var cy = (a1 * c2 - c1 * a2) / d;
|
||||
|
||||
points.push({x: bx1 + cx, y: by1 + cy, type: 1}); // line from point #0
|
||||
|
||||
// building arc segments
|
||||
var angleDistance = normalizeAngle(alpha2 - alpha1);
|
||||
var stepsCount = Math.ceil(Math.abs(angleDistance) / Math.PI * CIRCLE_APPROX_POINTS);
|
||||
var step = angleDistance / stepsCount;
|
||||
for (var i = 1; i <= stepsCount; i++) {
|
||||
var alpha = alpha1 + (angleDistance * i / stepsCount);
|
||||
var x_ = radiusX * Math.cos(alpha), y_ = radiusY * Math.sin(alpha);
|
||||
var x = x_ * rotationCos - y_ * rotationSin + cx;
|
||||
var y = x_ * rotationSin + y_ * rotationCos + cy;
|
||||
points.push({x: x, y: y, type: 4});
|
||||
}
|
||||
points[points.length - 1].type = 1;
|
||||
}
|
||||
|
||||
function PolygonTrackerNullOutput() {}
|
||||
PolygonTrackerNullOutput.prototype = {
|
||||
moveTo: function () {},
|
||||
lineTo: function () {},
|
||||
quadraticCurveTo: function () {},
|
||||
closePath: function () {}
|
||||
};
|
||||
|
||||
function PolygonTracker(target, hitCtx) {
|
||||
this.target = target || new PolygonTrackerNullOutput;
|
||||
this.segments = [0];
|
||||
this.points = [{x: 0, y: 0, type: 0}];
|
||||
this.hitCtx = hitCtx;
|
||||
}
|
||||
PolygonTracker.prototype = {
|
||||
get lineWidth() {
|
||||
return this.target.lineWidth;
|
||||
},
|
||||
set lineWidth(value) {
|
||||
this.target.lineWidth = value;
|
||||
},
|
||||
get lineCap() {
|
||||
return this.target.lineCap;
|
||||
},
|
||||
set lineCap(value) {
|
||||
this.target.lineCap = value;
|
||||
},
|
||||
get lineJoin() {
|
||||
return this.target.lineJoin;
|
||||
},
|
||||
set lineJoin(value) {
|
||||
this.target.lineJoin = value;
|
||||
},
|
||||
get miterLimit() {
|
||||
return this.target.miterLimit;
|
||||
},
|
||||
set miterLimit(value) {
|
||||
this.target.miterLimit = value;
|
||||
},
|
||||
moveTo: function (x, y) {
|
||||
var segmentStartIndex = this.segments[this.segments.length - 1];
|
||||
if (segmentStartIndex === this.points.length - 1) {
|
||||
this.points[segmentStartIndex].x = x;
|
||||
this.points[segmentStartIndex].y = y;
|
||||
} else {
|
||||
this.segments.push(this.points.length);
|
||||
this.points.push({x: x, y: y, type: 0});
|
||||
}
|
||||
this.target.moveTo(x, y);
|
||||
if (this.hitCtx)
|
||||
this.hitCtx.moveTo(x, y);
|
||||
},
|
||||
lineTo: function (x, y) {
|
||||
this.points.push({x: x, y: y, type: 1});
|
||||
this.target.lineTo(x, y);
|
||||
if (this.hitCtx)
|
||||
this.hitCtx.lineTo(x, y);
|
||||
},
|
||||
closePath: function () {
|
||||
var segmentStartIndex = this.segments[this.segments.length - 1];
|
||||
this.points.push({x: this.points[segmentStartIndex].x,
|
||||
y: this.points[segmentStartIndex].y,
|
||||
type: 2});
|
||||
|
||||
this.target.closePath();
|
||||
if (this.hitCtx)
|
||||
this.hitCtx.closePath();
|
||||
|
||||
this.segments.push(this.points.length);
|
||||
this.points.push({x: this.points[segmentStartIndex].x,
|
||||
y: this.points[segmentStartIndex].y,
|
||||
type: 0});
|
||||
},
|
||||
quadraticCurveTo: function (cpx, cpy, x, y) {
|
||||
pushCurveApprox(this.points, cpx, cpy, x, y);
|
||||
this.target.quadraticCurveTo(cpx, cpy, x, y);
|
||||
if (this.hitCtx)
|
||||
this.hitCtx.quadraticCurveTo(cpx, cpy, x, y);
|
||||
},
|
||||
bezierCurveTo: function (cpx1, cpy1, cpx2, cpy2, x, y) {
|
||||
pushBezierCurveApprox(this.points, cpx1, cpy1, cpx2, cpy2, x, y);
|
||||
this.target.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y);
|
||||
if (this.hitCtx)
|
||||
this.hitCtx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y);
|
||||
},
|
||||
arcTo: function (x1, y1, x2, y2, radiusX, radiusY, rotation) {
|
||||
pushArcApprox(this.points, x1, y1, x2, y2, radiusX,
|
||||
arguments.length < 6 ? radiusX : radiusY,
|
||||
rotation);
|
||||
this.target.arcTo.apply(this.target, arguments);
|
||||
if (this.hitCtx)
|
||||
this.hitCtx.arcTo.apply(this.hitCtx, arguments);
|
||||
},
|
||||
rect: function (x, y, w, h) {
|
||||
var segmentStartIndex = this.segments[this.segments.length - 1];
|
||||
if (segmentStartIndex === this.points.length - 1) {
|
||||
this.points[segmentStartIndex].x = x;
|
||||
this.points[segmentStartIndex].y = y;
|
||||
} else {
|
||||
this.segments.push(this.points.length);
|
||||
this.points.push({x: x, y: y, type: 0});
|
||||
}
|
||||
this.points.push({x: x + w, y: y, type: 1});
|
||||
this.points.push({x: x + w, y: y + h, type: 1});
|
||||
this.points.push({x: x, y: y + h, type: 1});
|
||||
this.points.push({x: x, y: y, type: 2});
|
||||
|
||||
this.target.rect(x, y, w, h);
|
||||
if (this.hitCtx)
|
||||
this.hitCtx.rect(x, y, w, h);
|
||||
},
|
||||
strokeToPath: function (output, options) {
|
||||
strokeToPath(this, options || {
|
||||
strokeWidth: this.lineWidth,
|
||||
startCap: this.lineCap,
|
||||
endCap: this.lineCap,
|
||||
join: this.lineJoin,
|
||||
miterLimit: this.miterLimit
|
||||
}, output);
|
||||
},
|
||||
getBounds: function () {
|
||||
var points = this.points;
|
||||
if (points.length <= 1) { // HACK only moveTo
|
||||
return null;
|
||||
}
|
||||
var minX, minY, maxX, maxY;
|
||||
minX = maxX = points[0].x;
|
||||
minY = maxY = points[0].y;
|
||||
for (var i = 1; i < points.length; i++) {
|
||||
var x = points[i].x, y = points[i].y;
|
||||
if (x < minX) minX = x;
|
||||
if (y < minY) minY = y;
|
||||
if (x > maxX) maxX = x;
|
||||
if (y > maxY) maxY = y;
|
||||
}
|
||||
return {minX: minX, minY: minY, maxX: maxX, maxY: maxY};
|
||||
}
|
||||
};
|
||||
return PolygonTracker;
|
||||
})();
|
||||
|
||||
def.__glue__ = {
|
||||
native: {
|
||||
instance: {
|
||||
|
@ -826,8 +286,9 @@ var GraphicsDefinition = (function () {
|
|||
copyFrom: def.copyFrom,
|
||||
cubicCurveTo: def.cubicCurveTo,
|
||||
curveTo: def.curveTo,
|
||||
drawCircle: def.drawCircle,
|
||||
drawEllipse: def.drawEllipse,
|
||||
drawPath: def.drawPath,
|
||||
drawPathObject: def.drawPathObject,
|
||||
drawRect: def.drawRect,
|
||||
drawRoundRect: def.drawRoundRect,
|
||||
drawRoundRectComplex: def.drawRoundRectComplex,
|
||||
|
|
|
@ -745,7 +745,7 @@ var LoaderDefinition = (function () {
|
|||
props.variableName = symbol.variableName;
|
||||
break;
|
||||
case 'shape':
|
||||
var createGraphicsData = new Function('d,r', 'return ' + symbol.data);
|
||||
var createGraphicsSubPaths = new Function('c,d,r', 'return ' + symbol.data);
|
||||
className = symbol.morph ? 'flash.display.MorphShape' : 'flash.display.Shape';
|
||||
props.bbox = symbol.bbox;
|
||||
props.graphicsFactory = function graphicsFactory(ratio) {
|
||||
|
@ -754,7 +754,7 @@ var LoaderDefinition = (function () {
|
|||
|
||||
var graphics = new flash.display.Graphics;
|
||||
graphics._scale = 0.05;
|
||||
graphics.drawGraphicsData(createGraphicsData(dictionary, ratio));
|
||||
graphics._subpaths = createGraphicsSubPaths(graphics, dictionary, ratio);
|
||||
|
||||
graphicsFactory[ratio] = graphics;
|
||||
|
||||
|
|
|
@ -30,32 +30,32 @@ function renderDisplayObject(child, ctx, transform, cxform, clip) {
|
|||
|
||||
var subpaths = graphics._subpaths;
|
||||
for (var j = 0, o = subpaths.length; j < o; j++) {
|
||||
var pathTracker = subpaths[j], path = pathTracker.target;
|
||||
var path = subpaths[j];
|
||||
|
||||
ctx.currentPath = path;
|
||||
|
||||
if (clip) {
|
||||
ctx.beginPath();
|
||||
ctx.__draw__(path);
|
||||
ctx.closePath();
|
||||
} else {
|
||||
if (path.fillStyle) {
|
||||
ctx.fillStyle = path.fillStyle;
|
||||
if (path.fillTransform) {
|
||||
var m = path.fillTransform;
|
||||
ctx.beginPath();
|
||||
ctx.__draw__(path);
|
||||
|
||||
var m = path.fillStyle.currentTransform;
|
||||
if (m) {
|
||||
ctx.save();
|
||||
ctx.transform(m.a, m.b, m.c, m.d, m.tx, m.ty);
|
||||
ctx.transform(m.a, m.b, m.c, m.d, m.e, m.f);
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
} else {
|
||||
ctx.fill(path);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
if (path.strokeStyle) {
|
||||
ctx.strokeStyle = path.strokeStyle;
|
||||
var drawingStyles = pathTracker.drawingStyles;
|
||||
var drawingStyles = path.drawingStyles;
|
||||
for (var prop in drawingStyles)
|
||||
ctx[prop] = drawingStyles[prop];
|
||||
ctx.stroke(path);
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -476,7 +476,6 @@ function renderStage(stage, ctx, onBeforeFrame, onAfterFrame) {
|
|||
if (renderDummyBalls) {
|
||||
renderDummyBalls();
|
||||
} else {
|
||||
visitContainer(stage, new MouseVisitor());
|
||||
flushPendingScripts();
|
||||
ctx.beginPath();
|
||||
visitContainer(stage, new PreVisitor(ctx));
|
||||
|
@ -488,6 +487,8 @@ function renderStage(stage, ctx, onBeforeFrame, onAfterFrame) {
|
|||
onAfterFrame();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
visitContainer(stage, new MouseVisitor());
|
||||
}
|
||||
requestAnimationFrame(draw);
|
||||
})();
|
||||
|
|
231
src/swf/shape.js
231
src/swf/shape.js
|
@ -7,13 +7,6 @@ var GRAPHICS_FILL_RADIAL_GRADIENT = 18;
|
|||
var GRAPHICS_FILL_REPEATING_BITMAP = 64;
|
||||
var GRAPHICS_FILL_SOLID = 0;
|
||||
|
||||
var GRAPHICS_PATH_COMMAND_CUBIC_CURVE_TO = 6;
|
||||
var GRAPHICS_PATH_COMMAND_CURVE_TO = 3;
|
||||
var GRAPHICS_PATH_COMMAND_LINE_TO = 2;
|
||||
var GRAPHICS_PATH_COMMAND_MOVE_TO = 1;
|
||||
var GRAPHICS_PATH_COMMAND_WIDE_LINE_TO = 5;
|
||||
var GRAPHICS_PATH_COMMAND_WIDE_MOVE_TO = 4;
|
||||
|
||||
function morph(start, end) {
|
||||
if (!isNaN(end) && end !== start)
|
||||
return start + '+' + (end - start) + '*r';
|
||||
|
@ -21,44 +14,35 @@ function morph(start, end) {
|
|||
return start;
|
||||
}
|
||||
function morphColor(color, colorMorph) {
|
||||
return '(' + morph(color.red, colorMorph.red) + ')<<16|' +
|
||||
'(' + morph(color.green, colorMorph.green) + ')<<8|' +
|
||||
'(' + morph(color.blue, colorMorph.blue) + ')';
|
||||
return '"rgba(" + (' +
|
||||
morph(color.red, colorMorph.red) + ') + "," + (' +
|
||||
morph(color.green, colorMorph.green) + ') + "," + (' +
|
||||
morph(color.blue, colorMorph.blue) + ') + "," + (' +
|
||||
morph(color.alpha / 255, colorMorph.alpha / 255) +
|
||||
') + ")"';
|
||||
}
|
||||
function toColorProperties(color, colorMorph) {
|
||||
if (colorMorph) {
|
||||
return 'color:' + morphColor(color, colorMorph) + ',' +
|
||||
'alpha:' + morph(color.alpha / 255, colorMorph.alpha / 255);
|
||||
}
|
||||
function toMatrixInstance(matrix, matrixMorph, scale) {
|
||||
if (scale === undefined)
|
||||
scale = 20;
|
||||
|
||||
if (color) {
|
||||
return 'color:' + (color.red << 16 | color.green << 8 | color.blue) + ',' +
|
||||
'alpha:' + (color.alpha / 255);
|
||||
}
|
||||
|
||||
return 'color: 0, alpha: 1';
|
||||
}
|
||||
function toMatrixInstance(matrix, matrixMorph) {
|
||||
if (matrixMorph) {
|
||||
return '{' +
|
||||
'__class__:"flash.geom.Matrix",' +
|
||||
'a:' + morph(matrix.a * 20, matrixMorph.a * 20) + ',' +
|
||||
'b:' + morph(matrix.b * 20, matrixMorph.b * 20) + ',' +
|
||||
'c:' + morph(matrix.c * 20, matrixMorph.c * 20) + ',' +
|
||||
'd:' + morph(matrix.d * 20, matrixMorph.d * 20) + ',' +
|
||||
'tx:' + morph(matrix.tx, matrixMorph.tx) + ',' +
|
||||
'ty:' + morph(matrix.ty, matrixMorph.ty) +
|
||||
'a:' + morph(matrix.a * scale, matrixMorph.a * scale) + ',' +
|
||||
'b:' + morph(matrix.b * scale, matrixMorph.b * scale) + ',' +
|
||||
'c:' + morph(matrix.c * scale, matrixMorph.c * scale) + ',' +
|
||||
'd:' + morph(matrix.d * scale, matrixMorph.d * scale) + ',' +
|
||||
'e:' + morph(matrix.tx * 20, matrixMorph.ty * 20) + ',' +
|
||||
'f:' + morph(matrix.tx * 20, matrixMorph.ty * 20) +
|
||||
'}';
|
||||
}
|
||||
|
||||
return '{' +
|
||||
'__class__:"flash.geom.Matrix",' +
|
||||
'a:' + (matrix.a * 20) + ',' +
|
||||
'b:' + (matrix.b * 20) + ',' +
|
||||
'c:' + (matrix.c * 20) + ',' +
|
||||
'd:' + (matrix.d * 20) + ',' +
|
||||
'tx:' + (matrix.tx * 20) + ',' +
|
||||
'ty:' + (matrix.ty * 20) +
|
||||
'a:' + (matrix.a * scale) + ',' +
|
||||
'b:' + (matrix.b * scale) + ',' +
|
||||
'c:' + (matrix.c * scale) + ',' +
|
||||
'd:' + (matrix.d * scale) + ',' +
|
||||
'e:' + (matrix.tx * 20) + ',' +
|
||||
'f:' + (matrix.ty * 20) +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
@ -272,117 +256,103 @@ function defineShape(tag, dictionary) {
|
|||
var commands = [];
|
||||
|
||||
var fillStyle = fillStyles[i - 1];
|
||||
var fill;
|
||||
switch (fillStyle.type) {
|
||||
case GRAPHICS_FILL_SOLID:
|
||||
commands.push('{' +
|
||||
'__class__:"flash.display.GraphicsSolidFill",' +
|
||||
'__isIGraphicsFill__:true,' +
|
||||
toColorProperties(fillStyle.color, fillStyle.colorMorph) +
|
||||
'}');
|
||||
if (fillStyle.colorMorph) {
|
||||
fill = morphColor(fillStyle.color, fillStyle.colorMorph);
|
||||
} else {
|
||||
var color = fillStyle.color
|
||||
fill = '"rgba(' + [color.red, color.green, color.blue, color.alpha / 255].join(',') + ')"';
|
||||
}
|
||||
break;
|
||||
case GRAPHICS_FILL_LINEAR_GRADIENT:
|
||||
case GRAPHICS_FILL_RADIAL_GRADIENT:
|
||||
case GRAPHICS_FILL_FOCAL_RADIAL_GRADIENT:
|
||||
var records = fillStyle.records;
|
||||
var colors = [];
|
||||
var alphas = [];
|
||||
var ratios = [];
|
||||
var stops = [];
|
||||
for (var j = 0, n = records.length; j < n; j++) {
|
||||
var record = records[j];
|
||||
var color = record.color;
|
||||
if (record.colorMorph) {
|
||||
var colorMorph = record.colorMorph;
|
||||
colors.push(morphColor(color, colorMorph));
|
||||
alphas.push(morph(color.alpha, colorMorph.alpha));
|
||||
ratios.push(morph(record.ratio, record.ratioMorph));
|
||||
stops.push('f.addColorStop(' +
|
||||
morph(record.ratio / 255, record.ratioMorph / 255) + ',' +
|
||||
morphColor(color, record.colorMorph) +
|
||||
')');
|
||||
} else {
|
||||
colors.push(color.red << 16 | color.green << 8 | color.blue);
|
||||
alphas.push(color.alpha);
|
||||
ratios.push(record.ratio);
|
||||
stops.push('f.addColorStop(' +
|
||||
(record.ratio / 255) + ',' +
|
||||
'"rgba(' + [color.red, color.green, color.blue, color.alpha / 255].join(',') + ')"' +
|
||||
')');
|
||||
}
|
||||
}
|
||||
commands.push('{' +
|
||||
'__class__:"flash.display.GraphicsGradientFill",' +
|
||||
'__isIGraphicsFill__:true,' +
|
||||
'type:' + (fillStyle.type == GRAPHICS_FILL_LINEAR_GRADIENT ? '"linear"' : '"radial"') + ',' +
|
||||
'colors:[' + colors.join(',') + '],' +
|
||||
'alphas:[' + alphas.join(',') + '],' +
|
||||
'ratios:[' + ratios.join(',') + '],' +
|
||||
'matrix:' + toMatrixInstance(fillStyle.matrix, fillStyle.matrixMorph),
|
||||
'spreadMode:"pad",' +
|
||||
'interpolationMode:"rgb",' +
|
||||
'focalPointRatio:' + morph(fillStyle.focalPoint, fillStyle.focalPointMorph) +
|
||||
'}');
|
||||
fill = '(' +
|
||||
'f=c._create' + (GRAPHICS_FILL_LINEAR_GRADIENT ? 'Linear' : 'Radial') + 'Gradient(' +
|
||||
(GRAPHICS_FILL_LINEAR_GRADIENT ?
|
||||
'-1, 0, 1, 0' :
|
||||
'(' + morph(fillStyle.focalPoint, fillStyle.focalPointMorph) + ' || 0), 0, 0, 0, 0, 1'
|
||||
) +
|
||||
'),' +
|
||||
stops.join(',') + ',' +
|
||||
'f.currentTransform=' +
|
||||
toMatrixInstance(fillStyle.matrix, fillStyle.matrixMorph, 20 * 819.2) + ',' +
|
||||
'f)';
|
||||
break;
|
||||
case GRAPHICS_FILL_REPEATING_BITMAP:
|
||||
case GRAPHICS_FILL_CLIPPED_BITMAP:
|
||||
case GRAPHICS_FILL_NONSMOOTHED_REPEATING_BITMAP:
|
||||
case GRAPHICS_FILL_NONSMOOTHED_CLIPPED_BITMAP:
|
||||
var bitmap = dictionary[fillStyle.bitmapId];
|
||||
commands.push('{' +
|
||||
'__class__:"flash.display.GraphicsBitmapFill",' +
|
||||
'__isIGraphicsFill__:true,' +
|
||||
'bitmapData: {' +
|
||||
'__class__:"flash.display.BitmapData",' +
|
||||
'_drawable:d[' + bitmap.id + '].value.props.img' +
|
||||
'},' +
|
||||
'matrix:' + toMatrixInstance(fillStyle.matrix, fillStyle.matrixMorph),
|
||||
'repeat:' + !!fillStyle.repeat +
|
||||
'}');
|
||||
dependencies.push(bitmap.id);
|
||||
fill = '(' +
|
||||
'f=c._createPattern(' +
|
||||
'd[' + bitmap.id + '].value.props.img,' +
|
||||
(fillStyle.repeat ? '"repeat"' : '"no-repeat"') +
|
||||
'),' +
|
||||
'f.currentTransform=' +
|
||||
toMatrixInstance(fillStyle.matrix, fillStyle.matrixMorph, 1) + ',' +
|
||||
'f)';
|
||||
break;
|
||||
default:
|
||||
fail('invalid fill style', 'shape');
|
||||
}
|
||||
|
||||
var cmds = [];
|
||||
var data = [];
|
||||
var j = 0;
|
||||
var subpath;
|
||||
var prev = { };
|
||||
while ((subpath = path[j++])) {
|
||||
if (subpath.spt !== prev.dpt) {
|
||||
cmds.push(GRAPHICS_PATH_COMMAND_MOVE_TO);
|
||||
data.push(subpath.spt);
|
||||
}
|
||||
if (subpath.spt !== prev.dpt)
|
||||
cmds.push('M' + subpath.spt);
|
||||
var edges = subpath.edges;
|
||||
if (subpath.flip) {
|
||||
var k = edges.length;
|
||||
var edge;
|
||||
while ((edge = edges[--k])) {
|
||||
if (edge.cpt) {
|
||||
cmds.push(GRAPHICS_PATH_COMMAND_CURVE_TO);
|
||||
data.push(edge.cpt, edge.spt);
|
||||
} else {
|
||||
cmds.push(GRAPHICS_PATH_COMMAND_LINE_TO);
|
||||
data.push(edge.spt);
|
||||
}
|
||||
if (edge.cpt)
|
||||
cmds.push('Q' + edge.cpt + ',' + edge.spt);
|
||||
else
|
||||
cmds.push('L' + edge.spt);
|
||||
}
|
||||
} else {
|
||||
var k = 0;
|
||||
var edge;
|
||||
while ((edge = edges[k++])) {
|
||||
if (edge.cpt) {
|
||||
cmds.push(GRAPHICS_PATH_COMMAND_CURVE_TO);
|
||||
data.push(edge.cpt, edge.dpt);
|
||||
} else {
|
||||
cmds.push(GRAPHICS_PATH_COMMAND_LINE_TO);
|
||||
data.push(edge.dpt);
|
||||
}
|
||||
if (edge.cpt)
|
||||
cmds.push('Q' + edge.cpt + ',' + edge.dpt);
|
||||
else
|
||||
cmds.push('L' + edge.dpt);
|
||||
}
|
||||
}
|
||||
prev = subpath;
|
||||
}
|
||||
|
||||
commands.push('{' +
|
||||
'__class__:"flash.display.GraphicsPath",' +
|
||||
'__isIGraphicsPath__:true,' +
|
||||
'commands:[' + cmds.join(',') + '],' +
|
||||
'data:[' + data.join(',') + ']' +
|
||||
'},{' +
|
||||
'__class__:"flash.display.GraphicsEndFill",' +
|
||||
'__isIGraphicsFill__:true' +
|
||||
'}');
|
||||
commands.push(
|
||||
'(' +
|
||||
'p=Kanvas.Path("' + cmds.join('') + '"),' +
|
||||
'p.fillStyle=' + fill + ',' +
|
||||
'p)'
|
||||
);
|
||||
|
||||
paths.push({ i: path[0].i, commands: commands});
|
||||
}
|
||||
|
@ -393,7 +363,11 @@ function defineShape(tag, dictionary) {
|
|||
while ((lineStyle = lineStyles[i++])) {
|
||||
var segments = lineSegments[i];
|
||||
if (segments) {
|
||||
var colorProps = toColorProperties(lineStyle.color, lineStyle.colorMorph);
|
||||
var color = lineStyle.color;
|
||||
var stroke = lineStyle.colorMorph ?
|
||||
morphColor(color, lineStyle.colorMorph) :
|
||||
'"rgba(' + [color.red, color.green, color.blue, color.alpha / 255].join(',') + ')"'
|
||||
;
|
||||
var lineWidth =
|
||||
morph(lineStyle.width || 20, isMorph ? lineStyle.widthMorph || 20 : undefined);
|
||||
// ignoring startCapStyle ?
|
||||
|
@ -404,7 +378,6 @@ function defineShape(tag, dictionary) {
|
|||
var miterLimitFactor = lineStyle.miterLimitFactor;
|
||||
|
||||
var cmds = [];
|
||||
var data = [];
|
||||
var j = 0;
|
||||
var prev = { };
|
||||
while ((segment = segments[j++])) {
|
||||
|
@ -412,17 +385,12 @@ function defineShape(tag, dictionary) {
|
|||
var k = 0;
|
||||
var edge;
|
||||
while ((edge = edges[k++])) {
|
||||
if (edge.spt !== prev.dpt) {
|
||||
cmds.push(GRAPHICS_PATH_COMMAND_MOVE_TO);
|
||||
data.push(edge.spt);
|
||||
}
|
||||
if (edge.cpt) {
|
||||
cmds.push(GRAPHICS_PATH_COMMAND_CURVE_TO);
|
||||
data.push(edge.cpt, edge.dpt);
|
||||
} else {
|
||||
cmds.push(GRAPHICS_PATH_COMMAND_LINE_TO);
|
||||
data.push(edge.dpt);
|
||||
}
|
||||
if (edge.spt !== prev.dpt)
|
||||
cmds.push('M' + edge.spt);
|
||||
if (edge.cpt)
|
||||
cmds.push('Q' + edge.cpt + ',' + edge.dpt);
|
||||
else
|
||||
cmds.push('L' + edge.dpt);
|
||||
prev = edge;
|
||||
}
|
||||
}
|
||||
|
@ -430,29 +398,16 @@ function defineShape(tag, dictionary) {
|
|||
paths.push({
|
||||
i: Number.MAX_VALUE,
|
||||
commands: [
|
||||
'{' +
|
||||
'__class__:"flash.display.GraphicsStroke",' +
|
||||
'__isIGraphicsStroke__:true,' +
|
||||
'thickness:' + lineWidth + ',' +
|
||||
'pixelHinting:false,' +
|
||||
'caps:"' + capsStyle + '",' +
|
||||
'joins:"' + joinStyle + '",' +
|
||||
'miterLimit:' + (miterLimitFactor * 2) + ',' +
|
||||
'scaleMode:"normal",' +
|
||||
'fill:{' +
|
||||
'__class__:"flash.display.GraphicsSolidFill",' +
|
||||
'__isIGraphicsFill__:true,' +
|
||||
colorProps +
|
||||
'}' +
|
||||
'},{' +
|
||||
'__class__:"flash.display.GraphicsPath",' +
|
||||
'__isIGraphicsPath__:true,' +
|
||||
'commands:[' + cmds.join(',') + '],' +
|
||||
'data:[' + data.join(',') + ']' +
|
||||
'},{' +
|
||||
'__isIGraphicsStroke__:true,' +
|
||||
'fill:null' +
|
||||
'}'
|
||||
'(' +
|
||||
'p=Kanvas.Path("' + cmds.join('') + '"),' +
|
||||
'p.strokeStyle=' + stroke + ',' +
|
||||
'p.drawingStyles={' +
|
||||
'lineWidth:' + lineWidth + ',' +
|
||||
'lineCap:"' + capsStyle + '",' +
|
||||
'lineJoin:"' + joinStyle + '",' +
|
||||
'miterLimit:' + (miterLimitFactor * 2) +
|
||||
'},' +
|
||||
'p)'
|
||||
]
|
||||
});
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче