Bug 520943 - Windows 7 taskbar previews does not respect browser's zoom level r=roc r=dao a-2.0=gavin

This commit is contained in:
Rob Arnold 2010-10-19 16:06:00 -07:00
Родитель b809a5b14f
Коммит 7b35b624dc
2 изменённых файлов: 47 добавлений и 15 удалений

Просмотреть файл

@ -132,6 +132,19 @@ function getFaviconAsImage(iconurl, callback) {
_imageFromURI(faviconSvc.defaultFavicon, callback);
}
// Snaps the given rectangle to be pixel-aligned at the given scale
function snapRectAtScale(r, scale) {
let x = Math.floor(r.x * scale);
let y = Math.floor(r.y * scale);
let width = Math.ceil((r.x + r.width) * scale) - x;
let height = Math.ceil((r.y + r.height) * scale) - y;
r.x = x / scale;
r.y = y / scale;
r.width = width / scale;
r.height = height / scale;
}
////////////////////////////////////////////////////////////////////////////////
//// PreviewController
@ -172,6 +185,13 @@ function PreviewController(win, tab) {
dirtyRegion.init();
return dirtyRegion;
});
XPCOMUtils.defineLazyGetter(this, "winutils",
function () {
let win = tab.linkedBrowser.contentWindow;
return win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
});
}
PreviewController.prototype = {
@ -214,6 +234,12 @@ PreviewController.prototype = {
this.canvasPreview.height = 0;
},
get zoom() {
// We use this property instead of the fullZoom property because this
// accurately reflects the actual zoom factor used when drawing.
return this.winutils.screenPixelsPerCSSPixel;
},
// Updates the controller's canvas with the parts of the <browser> that need
// to be redrawn.
updateCanvasPreview: function () {
@ -223,23 +249,30 @@ PreviewController.prototype = {
if (bx.width != this.canvasPreview.width ||
bx.height != this.canvasPreview.height) {
// Invalidate the entire area and repaint
this.onTabPaint({left:0, top:0, width:bx.width, height:bx.height});
this.onTabPaint({left:0, top:0, right:win.innerWidth, bottom:win.innerHeight});
this.canvasPreview.width = bx.width;
this.canvasPreview.height = bx.height;
}
// Draw dirty regions
let ctx = this.canvasPreview.getContext("2d");
let scale = this.zoom;
let flags = this.canvasPreviewFlags;
// width/height are occasionally bogus and too large for drawWindow
// so we clip to the canvas region
this.dirtyRegion.intersectRect(0, 0, bx.width, bx.height);
// The dirty region may include parts that are offscreen so we clip to the
// canvas area.
this.dirtyRegion.intersectRect(0, 0, win.innerWidth, win.innerHeight);
this.dirtyRects.forEach(function (r) {
// We need to snap the rectangle to be pixel aligned in the destination
// coordinate space. Otherwise natively themed widgets might not draw.
snapRectAtScale(r, scale);
let x = r.x;
let y = r.y;
let width = r.width;
let height = r.height;
ctx.save();
ctx.scale(scale, scale);
ctx.translate(x, y);
ctx.drawWindow(win, x, y, width, height, "white", flags);
ctx.restore();
@ -252,16 +285,11 @@ PreviewController.prototype = {
},
onTabPaint: function (rect) {
// Ignore spurious dirty rects
if (!rect.width || !rect.height)
return;
let r = { x: Math.floor(rect.left),
y: Math.floor(rect.top),
width: Math.ceil(rect.width),
height: Math.ceil(rect.height)
};
this.dirtyRegion.unionRect(r.x, r.y, r.width, r.height);
let x = Math.floor(rect.left),
y = Math.floor(rect.top),
width = Math.ceil(rect.right) - x,
height = Math.ceil(rect.bottom) - y;
this.dirtyRegion.unionRect(x, y, width, height);
},
updateTitleAndTooltip: function () {

Просмотреть файл

@ -405,11 +405,15 @@ gfxContext::UserToDevicePixelSnapped(gfxRect& rect, PRBool ignoreScale) const
// if we're not at 1.0 scale, don't snap, unless we're
// ignoring the scale. If we're not -just- a scale,
// never snap.
const gfxFloat epsilon = 0.0000001;
#define WITHIN_E(a,b) (fabs((a)-(b)) < epsilon)
cairo_matrix_t mat;
cairo_get_matrix(mCairo, &mat);
if (!ignoreScale &&
(mat.xx != 1.0 || mat.yy != 1.0 || mat.xy != 0.0 || mat.yx != 0.0))
(!WITHIN_E(mat.xx,1.0) || !WITHIN_E(mat.yy,1.0) ||
!WITHIN_E(mat.xy,0.0) || !WITHIN_E(mat.yx,0.0)))
return PR_FALSE;
#undef WITHIN_E
gfxPoint p1 = UserToDevice(rect.pos);
gfxPoint p2 = UserToDevice(rect.pos + gfxSize(rect.size.width, 0.0));