Commit cdb55d26 authored by Joel Martin's avatar Joel Martin

canvas.js: workaround WebKit bug, issue #28.

This is WebKit bug https://bugs.webkit.org/show_bug.cgi?id=46319

The workaround is to wrap Canvas render functions with a function that
sets a flush timer. The flush function sets the right margin and then
1ms later sets it back. This triggers the canvas to redraw with the
correct contents.

Two downsides:
- rendering is slower, but only on the busted versions of webkit.
  Correct and useful is better than fast and useless.
- There is a barely perceptible jitter of the control buttons because
  the canvas size is changing by one pixel.

To support this functionality, we also have to read out the exact
webkit version from the user agent in the render engine detection code
in include/util.js.
parent 455e4657
...@@ -25,8 +25,10 @@ var that = {}, // Public API interface ...@@ -25,8 +25,10 @@ var that = {}, // Public API interface
c_keyPress = null, c_keyPress = null,
c_mouseButton = null, c_mouseButton = null,
c_mouseMove = null; c_mouseMove = null,
c_webkit_bug = false,
c_flush_timer = null;
// Configuration settings // Configuration settings
function cdef(v, type, defval, desc) { function cdef(v, type, defval, desc) {
...@@ -91,7 +93,7 @@ that.get_height = function() { ...@@ -91,7 +93,7 @@ that.get_height = function() {
function constructor() { function constructor() {
Util.Debug(">> Canvas.init"); Util.Debug(">> Canvas.init");
var c, ctx, imgTest, tval, i, curDat, curSave, var c, ctx, func, origfunc, imgTest, tval, i, curDat, curSave,
has_imageData = false, UE = Util.Engine; has_imageData = false, UE = Util.Engine;
if (! conf.target) { throw("target must be set"); } if (! conf.target) { throw("target must be set"); }
...@@ -159,6 +161,26 @@ function constructor() { ...@@ -159,6 +161,26 @@ function constructor() {
that.cmapImage = that.cmapImageFill; that.cmapImage = that.cmapImageFill;
} }
if (UE.webkit && UE.webkit >= 534.7 && UE.webkit <= 534.9) {
// Workaround WebKit canvas rendering bug #46319
conf.render_mode += ", webkit bug workaround";
Util.Debug("Working around WebKit bug #46319");
c_webkit_bug = true;
for (func in {"fillRect":1, "copyImage":1, "rgbxImage":1,
"cmapImage":1, "blitStringImage":1}) {
that[func] = (function() {
var myfunc = that[func]; // Save original function
//Util.Debug("Wrapping " + func);
return function() {
myfunc.apply(this, arguments);
if (!c_flush_timer) {
c_flush_timer = setTimeout(that.flush, 100);
}
};
})();
}
}
/* /*
* Determine browser support for setting the cursor via data URI * Determine browser support for setting the cursor via data URI
* scheme * scheme
...@@ -483,6 +505,18 @@ that.stop = function() { ...@@ -483,6 +505,18 @@ that.stop = function() {
} }
}; };
that.flush = function() {
var old_val;
//Util.Debug(">> flush");
// Force canvas redraw (for webkit bug #46319 workaround)
old_val = conf.target.style.marginRight;
conf.target.style.marginRight = "1";
c_flush_timer = null;
setTimeout(function () {
conf.target.style.marginRight = old_val;
}, 1);
};
that.setFillColor = function(color) { that.setFillColor = function(color) {
var rgb, newStyle; var rgb, newStyle;
if (conf.true_color) { if (conf.true_color) {
......
...@@ -208,6 +208,14 @@ Util.Engine = { ...@@ -208,6 +208,14 @@ Util.Engine = {
'gecko': (function() { 'gecko': (function() {
return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }()) return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }())
}; };
if (Util.Engine.webkit) {
// Extract actual webkit version if available
Util.Engine.webkit = (function(v) {
var re = new RegExp('WebKit/([0-9\.]*) ');
v = (navigator.userAgent.match(re) || ['', v])[1];
return parseFloat(v, 10);
})(Util.Engine.webkit);
}
Util.Flash = (function(){ Util.Flash = (function(){
var v, version; var v, version;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment