Skip to content

Commit

Permalink
Fix(): Cache over invalidation bug (#10363)
Browse files Browse the repository at this point in the history
  • Loading branch information
asturur authored Dec 27, 2024
1 parent fe663c7 commit 95cddf5
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 50 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [5.5.1]

- fix(): Cache over invalidation bug backport from 6.x

## [5.5.0]

- refactor() Possibly breaking: Include text line height in text on a path size calculation to avoid cut off from cache. [`#10355`](https://github.com/fabricjs/fabric.js/pull/10355)
Expand Down
27 changes: 7 additions & 20 deletions dist/fabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -15180,8 +15180,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
// for sure this ALIASING_LIMIT is slightly creating problem
// in situation in which the cache canvas gets an upper limit
// also objectScale contains already scaleX and scaleY
width: neededX + ALIASING_LIMIT,
height: neededY + ALIASING_LIMIT,
width: Math.ceil(neededX + ALIASING_LIMIT),
height: Math.ceil(neededY + ALIASING_LIMIT),
zoomX: objectScale.scaleX,
zoomY: objectScale.scaleY,
x: neededX,
Expand All @@ -15206,29 +15206,16 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
}
var canvas = this._cacheCanvas,
dims = this._limitCacheSize(this._getCacheCanvasDimensions()),
minCacheSize = fabric.minCacheSideLimit,
width = dims.width, height = dims.height, drawingWidth, drawingHeight,
zoomX = dims.zoomX, zoomY = dims.zoomY,
dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,
zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,
shouldRedraw = dimensionsChanged || zoomChanged,
additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;
if (dimensionsChanged) {
var canvasWidth = this._cacheCanvas.width,
canvasHeight = this._cacheCanvas.height,
sizeGrowing = width > canvasWidth || height > canvasHeight,
sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&
canvasWidth > minCacheSize && canvasHeight > minCacheSize;
shouldResizeCanvas = sizeGrowing || sizeShrinking;
if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {
additionalWidth = width * 0.1;
additionalHeight = height * 0.1;
}
}
shouldRedraw = dimensionsChanged || zoomChanged;

if (shouldRedraw) {
if (shouldResizeCanvas) {
canvas.width = Math.ceil(width + additionalWidth);
canvas.height = Math.ceil(height + additionalHeight);
if (dimensionsChanged) {
canvas.width = width;
canvas.height = height;
}
else {
this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);
Expand Down
2 changes: 1 addition & 1 deletion dist/fabric.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "fabric",
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
"homepage": "http://fabricjs.com/",
"version": "5.5.0",
"version": "5.5.1",
"author": "Juriy Zaytsev <[email protected]>",
"contributors": [
{
Expand Down
27 changes: 7 additions & 20 deletions src/shapes/object.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,8 @@
// for sure this ALIASING_LIMIT is slightly creating problem
// in situation in which the cache canvas gets an upper limit
// also objectScale contains already scaleX and scaleY
width: neededX + ALIASING_LIMIT,
height: neededY + ALIASING_LIMIT,
width: Math.ceil(neededX + ALIASING_LIMIT),
height: Math.ceil(neededY + ALIASING_LIMIT),
zoomX: objectScale.scaleX,
zoomY: objectScale.scaleY,
x: neededX,
Expand All @@ -760,29 +760,16 @@
}
var canvas = this._cacheCanvas,
dims = this._limitCacheSize(this._getCacheCanvasDimensions()),
minCacheSize = fabric.minCacheSideLimit,
width = dims.width, height = dims.height, drawingWidth, drawingHeight,
zoomX = dims.zoomX, zoomY = dims.zoomY,
dimensionsChanged = width !== this.cacheWidth || height !== this.cacheHeight,
zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY,
shouldRedraw = dimensionsChanged || zoomChanged,
additionalWidth = 0, additionalHeight = 0, shouldResizeCanvas = false;
if (dimensionsChanged) {
var canvasWidth = this._cacheCanvas.width,
canvasHeight = this._cacheCanvas.height,
sizeGrowing = width > canvasWidth || height > canvasHeight,
sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&
canvasWidth > minCacheSize && canvasHeight > minCacheSize;
shouldResizeCanvas = sizeGrowing || sizeShrinking;
if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) {
additionalWidth = width * 0.1;
additionalHeight = height * 0.1;
}
}
shouldRedraw = dimensionsChanged || zoomChanged;

if (shouldRedraw) {
if (shouldResizeCanvas) {
canvas.width = Math.ceil(width + additionalWidth);
canvas.height = Math.ceil(height + additionalHeight);
if (dimensionsChanged) {
canvas.width = width;
canvas.height = height;
}
else {
this._cacheContext.setTransform(1, 0, 0, 1, 0, 0);
Expand Down
2 changes: 1 addition & 1 deletion test/unit/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -2365,7 +2365,7 @@
var done = assert.async();
assert.ok(typeof canvas.fxRemove === 'function');

var rect = new fabric.Rect();
var rect = new fabric.Rect({ width: 1, height: 1 });
canvas.add(rect);

var callbackFired = false;
Expand Down
13 changes: 7 additions & 6 deletions test/unit/canvas_static.js
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@

QUnit.test('loadFromJSON with text', function(assert) {
var done = assert.async();
var json = '{"objects":[{"type":"text","left":150,"top":200,"width":128,"height":64.32,"fill":"#000000","stroke":"","strokeWidth":"","scaleX":0.8,"scaleY":0.8,"angle":0,"flipX":false,"flipY":false,"opacity":1,"text":"NAME HERE","fontSize":24,"fontWeight":"","fontFamily":"Delicious_500","fontStyle":"","lineHeight":"","textDecoration":"","textAlign":"center","path":"","strokeStyle":"","backgroundColor":""}],"background":"#ffffff"}';
var json = '{"objects":[{"type":"text","left":150,"top":200,"width":128,"height":64.32,"fill":"#000000","stroke":"","strokeWidth":"","scaleX":0.8,"scaleY":0.8,"angle":0,"flipX":false,"flipY":false,"opacity":1,"text":"NAME HERE","fontSize":24,"fontWeight":"","fontFamily":"Delicious_500","fontStyle":"","lineHeight":1.16,"textDecoration":"","textAlign":"center","path":"","strokeStyle":"","backgroundColor":""}],"background":"#ffffff"}';
canvas.loadFromJSON(json, function() {

canvas.renderAll();
Expand All @@ -1319,11 +1319,12 @@
});

QUnit.test('loadFromJSON with clipPath', function(assert) {
var canvas2 = new fabric.StaticCanvas(null, { width: 400, height: 400, renderOnAddRemove: false });
var done = assert.async();
var json = '{"clipPath": {"type":"text","left":150,"top":200,"width":128,"height":64.32,"fill":"#000000","stroke":"","strokeWidth":"","scaleX":0.8,"scaleY":0.8,"angle":0,"flipX":false,"flipY":false,"opacity":1,"text":"NAME HERE","fontSize":24,"fontWeight":"","fontFamily":"Delicious_500","fontStyle":"","lineHeight":"","textDecoration":"","textAlign":"center","path":"","strokeStyle":"","backgroundColor":""}}';
canvas.loadFromJSON(json, function() {
canvas.renderAll();
assert.equal('text', canvas.clipPath.type);
var json = '{"clipPath": {"type":"text","left":150,"top":200,"width":128,"height":64.32,"fill":"#000000","stroke":"","strokeWidth":"","scaleX":0.8,"scaleY":0.8,"angle":0,"flipX":false,"flipY":false,"opacity":1,"text":"NAME HERE","fontSize":24,"fontWeight":"","fontFamily":"Delicious_500","fontStyle":"","lineHeight":1.16,"textDecoration":"","textAlign":"center","path":"","strokeStyle":"","backgroundColor":""}}';
canvas2.loadFromJSON(json, function() {
assert.equal('text', canvas2.clipPath.type);
canvas2.dispose();
done();
});
});
Expand Down Expand Up @@ -1644,7 +1645,7 @@
callbackFired = true;
assert.equal(canvas.item(0), undefined);
assert.ok(callbackFired);
canvas.cancelRequestedRender();
canvas.renderAll();
done();
}

Expand Down

0 comments on commit 95cddf5

Please sign in to comment.