mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-19 11:01:08 +00:00
Apply sencha patch to excanvas (http://dev.sencha.com/playpen/tm/excanvas-patch/)
This commit is contained in:
parent
8bd52f98fb
commit
3645c9ce6e
3 changed files with 1697 additions and 37 deletions
196
lib/excanvas-diff.patch
Normal file
196
lib/excanvas-diff.patch
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
Index: excanvas.js
|
||||
===================================================================
|
||||
--- excanvas.js (revision 63)
|
||||
+++ excanvas.js (working copy)
|
||||
@@ -255,6 +255,7 @@
|
||||
o2.arcScaleX_ = o1.arcScaleX_;
|
||||
o2.arcScaleY_ = o1.arcScaleY_;
|
||||
o2.lineScale_ = o1.lineScale_;
|
||||
+ o2.rotation_ = o1.rotation_; // used for images
|
||||
}
|
||||
|
||||
var colorData = {
|
||||
@@ -599,6 +600,7 @@
|
||||
this.arcScaleX_ = 1;
|
||||
this.arcScaleY_ = 1;
|
||||
this.lineScale_ = 1;
|
||||
+ this.rotation_ = 0;
|
||||
}
|
||||
|
||||
var contextPrototype = CanvasRenderingContext2D_.prototype;
|
||||
@@ -763,23 +765,31 @@
|
||||
return gradient;
|
||||
};
|
||||
|
||||
- contextPrototype.drawImage = function(image, var_args) {
|
||||
+ contextPrototype.drawImage = function(image) {
|
||||
var dx, dy, dw, dh, sx, sy, sw, sh;
|
||||
-
|
||||
+
|
||||
+ // to fix new Image() we check the existance of runtimeStyle
|
||||
+ var rts = image.runtimeStyle.width;
|
||||
+
|
||||
// to find the original width we overide the width and height
|
||||
- var oldRuntimeWidth = image.runtimeStyle.width;
|
||||
- var oldRuntimeHeight = image.runtimeStyle.height;
|
||||
- image.runtimeStyle.width = 'auto';
|
||||
- image.runtimeStyle.height = 'auto';
|
||||
+ if(rts) {
|
||||
+ var oldRuntimeWidth = image.runtimeStyle.width;
|
||||
+ var oldRuntimeHeight = image.runtimeStyle.height;
|
||||
+
|
||||
+ image.runtimeStyle.width = 'auto';
|
||||
+ image.runtimeStyle.height = 'auto';
|
||||
+ }
|
||||
|
||||
// get the original size
|
||||
var w = image.width;
|
||||
var h = image.height;
|
||||
-
|
||||
+
|
||||
// and remove overides
|
||||
- image.runtimeStyle.width = oldRuntimeWidth;
|
||||
- image.runtimeStyle.height = oldRuntimeHeight;
|
||||
-
|
||||
+ if(rts) {
|
||||
+ image.runtimeStyle.width = oldRuntimeWidth;
|
||||
+ image.runtimeStyle.height = oldRuntimeHeight;
|
||||
+ }
|
||||
+
|
||||
if (arguments.length == 3) {
|
||||
dx = arguments[1];
|
||||
dy = arguments[2];
|
||||
@@ -816,29 +826,44 @@
|
||||
|
||||
var W = 10;
|
||||
var H = 10;
|
||||
+
|
||||
+ var scaleX = scaleY = 1;
|
||||
+
|
||||
+ // FIX: divs give better quality then vml image and also fixes transparent PNG's
|
||||
+ vmlStr.push(' <div style="position:absolute;');
|
||||
|
||||
- // For some reason that I've now forgotten, using divs didn't work
|
||||
- vmlStr.push(' <g_vml_:group',
|
||||
- ' coordsize="', Z * W, ',', Z * H, '"',
|
||||
- ' coordorigin="0,0"' ,
|
||||
- ' style="width:', W, 'px;height:', H, 'px;position:absolute;');
|
||||
-
|
||||
// If filters are necessary (rotation exists), create them
|
||||
// filters are bog-slow, so only create them if abbsolutely necessary
|
||||
// The following check doesn't account for skews (which don't exist
|
||||
// in the canvas spec (yet) anyway.
|
||||
-
|
||||
if (this.m_[0][0] != 1 || this.m_[0][1] ||
|
||||
this.m_[1][1] != 1 || this.m_[1][0]) {
|
||||
var filter = [];
|
||||
|
||||
- // Note the 12/21 reversal
|
||||
- filter.push('M11=', this.m_[0][0], ',',
|
||||
- 'M12=', this.m_[1][0], ',',
|
||||
- 'M21=', this.m_[0][1], ',',
|
||||
- 'M22=', this.m_[1][1], ',',
|
||||
- 'Dx=', mr(d.x / Z), ',',
|
||||
- 'Dy=', mr(d.y / Z), '');
|
||||
+ // Scaling images using width & height instead of Transform Matrix
|
||||
+ // because of quality loss
|
||||
+ var c = mc(this.rotation_);
|
||||
+ var s = ms(this.rotation_);
|
||||
+
|
||||
+ // Inverse rotation matrix
|
||||
+ var irm = [
|
||||
+ [c, -s, 0],
|
||||
+ [s, c, 0],
|
||||
+ [0, 0, 1]
|
||||
+ ];
|
||||
+
|
||||
+ // Get unrotated matrix to get only scaling values
|
||||
+ var urm = matrixMultiply(irm, this.m_);
|
||||
+ scaleX = urm[0][0];
|
||||
+ scaleY = urm[1][1];
|
||||
+
|
||||
+ // Apply only rotation and translation to Matrix
|
||||
+ filter.push('M11=', c, ',',
|
||||
+ 'M12=', -s, ',',
|
||||
+ 'M21=', s, ',',
|
||||
+ 'M22=', c, ',',
|
||||
+ 'Dx=', d.x / Z, ',',
|
||||
+ 'Dy=', d.y / Z);
|
||||
|
||||
// Bounding box calculation (need to minimize displayed area so that
|
||||
// filters don't waste time on unused pixels.
|
||||
@@ -853,23 +878,40 @@
|
||||
vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
|
||||
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
|
||||
filter.join(''), ", sizingmethod='clip');");
|
||||
-
|
||||
} else {
|
||||
vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
|
||||
}
|
||||
|
||||
- vmlStr.push(' ">' ,
|
||||
- '<g_vml_:image src="', image.src, '"',
|
||||
- ' style="width:', Z * dw, 'px;',
|
||||
- ' height:', Z * dh, 'px"',
|
||||
- ' cropleft="', sx / w, '"',
|
||||
- ' croptop="', sy / h, '"',
|
||||
- ' cropright="', (w - sx - sw) / w, '"',
|
||||
- ' cropbottom="', (h - sy - sh) / h, '"',
|
||||
- ' />',
|
||||
- '</g_vml_:group>');
|
||||
+ vmlStr.push(' ">');
|
||||
|
||||
- this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
|
||||
+ // Draw a special cropping div if needed
|
||||
+ if (sx || sy) {
|
||||
+ // Apply scales to width and height
|
||||
+ vmlStr.push('<div style="overflow: hidden; width:', Math.ceil((dw + sx * dw / sw) * scaleX), 'px;',
|
||||
+ ' height:', Math.ceil((dh + sy * dh / sh) * scaleY), 'px;',
|
||||
+ ' filter:progid:DxImageTransform.Microsoft.Matrix(Dx=',
|
||||
+ -sx * dw / sw * scaleX, ',Dy=', -sy * dh / sh * scaleY, ');">');
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ // Apply scales to width and height
|
||||
+ vmlStr.push('<div style="width:', Math.round(scaleX * w * dw / sw), 'px;',
|
||||
+ ' height:', Math.round(scaleY * h * dh / sh), 'px;',
|
||||
+ ' filter:');
|
||||
+
|
||||
+ // If there is a globalAlpha, apply it to image
|
||||
+ if(this.globalAlpha < 1) {
|
||||
+ vmlStr.push(' progid:DXImageTransform.Microsoft.Alpha(opacity=' + (this.globalAlpha * 100) + ')');
|
||||
+ }
|
||||
+
|
||||
+ vmlStr.push(' progid:DXImageTransform.Microsoft.AlphaImageLoader(src=', image.src, ',sizingMethod=scale)">');
|
||||
+
|
||||
+ // Close the crop div if necessary
|
||||
+ if (sx || sy) vmlStr.push('</div>');
|
||||
+
|
||||
+ vmlStr.push('</div></div>');
|
||||
+
|
||||
+ this.element_.insertAdjacentHTML('beforeEnd', vmlStr.join(''));
|
||||
};
|
||||
|
||||
contextPrototype.stroke = function(aFill) {
|
||||
@@ -1155,6 +1197,8 @@
|
||||
var c = mc(aRot);
|
||||
var s = ms(aRot);
|
||||
|
||||
+ this.rotation_ += aRot;
|
||||
+
|
||||
var m1 = [
|
||||
[c, s, 0],
|
||||
[-s, c, 0],
|
||||
@@ -1308,7 +1352,11 @@
|
||||
}
|
||||
var doc = this.element_.ownerDocument;
|
||||
this.textMeasureEl_.innerHTML = '';
|
||||
- this.textMeasureEl_.style.font = this.font;
|
||||
+ // FIX: Apply current font style to textMeasureEl to get correct size
|
||||
+ var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_),
|
||||
+ fontStyleString = buildStyle(fontStyle);
|
||||
+ this.textMeasureEl_.style.font = fontStyleString;
|
||||
+
|
||||
// Don't use innerHTML or innerText because they allow markup/whitespace.
|
||||
this.textMeasureEl_.appendChild(doc.createTextNode(text));
|
||||
return {width: this.textMeasureEl_.offsetWidth};
|
||||
122
lib/excanvas.js
122
lib/excanvas.js
|
|
@ -253,6 +253,7 @@ if (!document.createElement('canvas').getContext) {
|
|||
o2.arcScaleX_ = o1.arcScaleX_;
|
||||
o2.arcScaleY_ = o1.arcScaleY_;
|
||||
o2.lineScale_ = o1.lineScale_;
|
||||
o2.rotation_ = o1.rotation_; // used for images
|
||||
}
|
||||
|
||||
var colorData = {
|
||||
|
|
@ -603,6 +604,7 @@ if (!document.createElement('canvas').getContext) {
|
|||
this.arcScaleX_ = 1;
|
||||
this.arcScaleY_ = 1;
|
||||
this.lineScale_ = 1;
|
||||
this.rotation_ = 0;
|
||||
}
|
||||
|
||||
var contextPrototype = CanvasRenderingContext2D_.prototype;
|
||||
|
|
@ -767,23 +769,31 @@ if (!document.createElement('canvas').getContext) {
|
|||
return gradient;
|
||||
};
|
||||
|
||||
contextPrototype.drawImage = function(image, var_args) {
|
||||
contextPrototype.drawImage = function(image) {
|
||||
var dx, dy, dw, dh, sx, sy, sw, sh;
|
||||
|
||||
|
||||
// to fix new Image() we check the existance of runtimeStyle
|
||||
var rts = image.runtimeStyle.width;
|
||||
|
||||
// to find the original width we overide the width and height
|
||||
var oldRuntimeWidth = image.runtimeStyle.width;
|
||||
var oldRuntimeHeight = image.runtimeStyle.height;
|
||||
image.runtimeStyle.width = 'auto';
|
||||
image.runtimeStyle.height = 'auto';
|
||||
if(rts) {
|
||||
var oldRuntimeWidth = image.runtimeStyle.width;
|
||||
var oldRuntimeHeight = image.runtimeStyle.height;
|
||||
|
||||
image.runtimeStyle.width = 'auto';
|
||||
image.runtimeStyle.height = 'auto';
|
||||
}
|
||||
|
||||
// get the original size
|
||||
var w = image.width;
|
||||
var h = image.height;
|
||||
|
||||
|
||||
// and remove overides
|
||||
image.runtimeStyle.width = oldRuntimeWidth;
|
||||
image.runtimeStyle.height = oldRuntimeHeight;
|
||||
|
||||
if(rts) {
|
||||
image.runtimeStyle.width = oldRuntimeWidth;
|
||||
image.runtimeStyle.height = oldRuntimeHeight;
|
||||
}
|
||||
|
||||
if (arguments.length == 3) {
|
||||
dx = arguments[1];
|
||||
dy = arguments[2];
|
||||
|
|
@ -820,29 +830,44 @@ if (!document.createElement('canvas').getContext) {
|
|||
|
||||
var W = 10;
|
||||
var H = 10;
|
||||
|
||||
// For some reason that I've now forgotten, using divs didn't work
|
||||
vmlStr.push(' <g_vml_:group',
|
||||
' coordsize="', Z * W, ',', Z * H, '"',
|
||||
' coordorigin="0,0"' ,
|
||||
' style="width:', W, 'px;height:', H, 'px;position:absolute;');
|
||||
|
||||
var scaleX = scaleY = 1;
|
||||
|
||||
// FIX: divs give better quality then vml image and also fixes transparent PNG's
|
||||
vmlStr.push(' <div style="position:absolute;');
|
||||
|
||||
// If filters are necessary (rotation exists), create them
|
||||
// filters are bog-slow, so only create them if abbsolutely necessary
|
||||
// The following check doesn't account for skews (which don't exist
|
||||
// in the canvas spec (yet) anyway.
|
||||
|
||||
if (this.m_[0][0] != 1 || this.m_[0][1] ||
|
||||
this.m_[1][1] != 1 || this.m_[1][0]) {
|
||||
var filter = [];
|
||||
|
||||
// Note the 12/21 reversal
|
||||
filter.push('M11=', this.m_[0][0], ',',
|
||||
'M12=', this.m_[1][0], ',',
|
||||
'M21=', this.m_[0][1], ',',
|
||||
'M22=', this.m_[1][1], ',',
|
||||
'Dx=', mr(d.x / Z), ',',
|
||||
'Dy=', mr(d.y / Z), '');
|
||||
// Scaling images using width & height instead of Transform Matrix
|
||||
// because of quality loss
|
||||
var c = mc(this.rotation_);
|
||||
var s = ms(this.rotation_);
|
||||
|
||||
// Inverse rotation matrix
|
||||
var irm = [
|
||||
[c, -s, 0],
|
||||
[s, c, 0],
|
||||
[0, 0, 1]
|
||||
];
|
||||
|
||||
// Get unrotated matrix to get only scaling values
|
||||
var urm = matrixMultiply(irm, this.m_);
|
||||
scaleX = urm[0][0];
|
||||
scaleY = urm[1][1];
|
||||
|
||||
// Apply only rotation and translation to Matrix
|
||||
filter.push('M11=', c, ',',
|
||||
'M12=', -s, ',',
|
||||
'M21=', s, ',',
|
||||
'M22=', c, ',',
|
||||
'Dx=', d.x / Z, ',',
|
||||
'Dy=', d.y / Z);
|
||||
|
||||
// Bounding box calculation (need to minimize displayed area so that
|
||||
// filters don't waste time on unused pixels.
|
||||
|
|
@ -857,23 +882,40 @@ if (!document.createElement('canvas').getContext) {
|
|||
vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
|
||||
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
|
||||
filter.join(''), ", sizingmethod='clip');");
|
||||
|
||||
} else {
|
||||
vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
|
||||
}
|
||||
|
||||
vmlStr.push(' ">' ,
|
||||
'<g_vml_:image src="', image.src, '"',
|
||||
' style="width:', Z * dw, 'px;',
|
||||
' height:', Z * dh, 'px"',
|
||||
' cropleft="', sx / w, '"',
|
||||
' croptop="', sy / h, '"',
|
||||
' cropright="', (w - sx - sw) / w, '"',
|
||||
' cropbottom="', (h - sy - sh) / h, '"',
|
||||
' />',
|
||||
'</g_vml_:group>');
|
||||
vmlStr.push(' ">');
|
||||
|
||||
this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
|
||||
// Draw a special cropping div if needed
|
||||
if (sx || sy) {
|
||||
// Apply scales to width and height
|
||||
vmlStr.push('<div style="overflow: hidden; width:', Math.ceil((dw + sx * dw / sw) * scaleX), 'px;',
|
||||
' height:', Math.ceil((dh + sy * dh / sh) * scaleY), 'px;',
|
||||
' filter:progid:DxImageTransform.Microsoft.Matrix(Dx=',
|
||||
-sx * dw / sw * scaleX, ',Dy=', -sy * dh / sh * scaleY, ');">');
|
||||
}
|
||||
|
||||
|
||||
// Apply scales to width and height
|
||||
vmlStr.push('<div style="width:', Math.round(scaleX * w * dw / sw), 'px;',
|
||||
' height:', Math.round(scaleY * h * dh / sh), 'px;',
|
||||
' filter:');
|
||||
|
||||
// If there is a globalAlpha, apply it to image
|
||||
if(this.globalAlpha < 1) {
|
||||
vmlStr.push(' progid:DXImageTransform.Microsoft.Alpha(opacity=' + (this.globalAlpha * 100) + ')');
|
||||
}
|
||||
|
||||
vmlStr.push(' progid:DXImageTransform.Microsoft.AlphaImageLoader(src=', image.src, ',sizingMethod=scale)">');
|
||||
|
||||
// Close the crop div if necessary
|
||||
if (sx || sy) vmlStr.push('</div>');
|
||||
|
||||
vmlStr.push('</div></div>');
|
||||
|
||||
this.element_.insertAdjacentHTML('beforeEnd', vmlStr.join(''));
|
||||
};
|
||||
|
||||
contextPrototype.stroke = function(aFill) {
|
||||
|
|
@ -1156,6 +1198,8 @@ if (!document.createElement('canvas').getContext) {
|
|||
var c = mc(aRot);
|
||||
var s = ms(aRot);
|
||||
|
||||
this.rotation_ += aRot;
|
||||
|
||||
var m1 = [
|
||||
[c, s, 0],
|
||||
[-s, c, 0],
|
||||
|
|
@ -1309,7 +1353,11 @@ if (!document.createElement('canvas').getContext) {
|
|||
}
|
||||
var doc = this.element_.ownerDocument;
|
||||
this.textMeasureEl_.innerHTML = '';
|
||||
this.textMeasureEl_.style.font = this.font;
|
||||
// FIX: Apply current font style to textMeasureEl to get correct size
|
||||
var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_),
|
||||
fontStyleString = buildStyle(fontStyle);
|
||||
this.textMeasureEl_.style.font = fontStyleString;
|
||||
|
||||
// Don't use innerHTML or innerText because they allow markup/whitespace.
|
||||
this.textMeasureEl_.appendChild(doc.createTextNode(text));
|
||||
return {width: this.textMeasureEl_.offsetWidth};
|
||||
|
|
|
|||
1416
lib/excanvas.js.orig
Normal file
1416
lib/excanvas.js.orig
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue