This commit is contained in:
Andrea Bogazzi 2017-02-27 02:34:04 +01:00 committed by GitHub
parent 99dbf469a4
commit 920c56ce52
8 changed files with 151 additions and 128 deletions

View file

@ -1,3 +1,14 @@
**Version 1.7.7**
- Fix for opacity parsing in svg with nested opacities [#3747] (https://github.com/kangax/fabric.js/pull/3747)
- Fix text initialization and boundingrect [#3745] (https://github.com/kangax/fabric.js/pull/3745)
- Fix line bounding box [#3742] (https://github.com/kangax/fabric.js/pull/3742)
- Improvement: do not pollute style object while typing if not necessary [#3743](https://github.com/kangax/fabric.js/pull/3743)
- fix for broken prototype chain when restoring a dataless object on fill an stroke [#3735](https://github.com/kangax/fabric.js/pull/3735)
- fix for deselected event not fired on mouse actions [#3716](https://github.com/kangax/fabric.js/pull/3716)
- fix for blurriness introduced on 1.7.3 [#3721](https://github.com/kangax/fabric.js/pull/3721)
**Version 1.7.6**
- Fix: make the cacheCanvas created on the fly if not available [#3705](https://github.com/kangax/fabric.js/pull/3705)

View file

@ -1,6 +1,6 @@
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: "1.7.6" };
var fabric = fabric || { version: "1.7.7" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}

View file

@ -25,7 +25,7 @@ Remove the template from below and provide thoughtful commentary *and code sampl
<!-- BUG TEMPLATE -->
## Version
1.7.6
1.7.7
## Test Case
http://jsfiddle.net/fabricjs/Da7SP/

134
dist/fabric.js vendored
View file

@ -3242,7 +3242,8 @@ if (typeof console !== 'undefined') {
'stroke-opacity': 'strokeOpacity',
'stroke-width': 'strokeWidth',
'text-decoration': 'textDecoration',
'text-anchor': 'originX'
'text-anchor': 'originX',
opacity: 'opacity'
},
colorAttributes = {
@ -3294,6 +3295,12 @@ if (typeof console !== 'undefined') {
value = false;
}
}
else if (attr === 'opacity') {
value = parseFloat(value);
if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {
value *= parentAttributes.opacity;
}
}
else if (attr === 'originX' /* text-anchor */) {
value = value === 'start' ? 'left' : value === 'end' ? 'right' : 'center';
}
@ -3512,8 +3519,8 @@ if (typeof console !== 'undefined') {
style.replace(/;\s*$/, '').split(';').forEach(function (chunk) {
var pair = chunk.split(':');
attr = normalizeAttr(pair[0].trim().toLowerCase());
value = normalizeValue(attr, pair[1].trim());
attr = pair[0].trim().toLowerCase();
value = pair[1].trim();
oStyle[attr] = value;
});
@ -3529,8 +3536,8 @@ if (typeof console !== 'undefined') {
continue;
}
attr = normalizeAttr(prop.toLowerCase());
value = normalizeValue(attr, style[prop]);
attr = prop.toLowerCase();
value = style[prop];
oStyle[attr] = value;
}
@ -3959,23 +3966,27 @@ if (typeof console !== 'undefined') {
var ownAttributes = attributes.reduce(function(memo, attr) {
value = element.getAttribute(attr);
if (value) {
attr = normalizeAttr(attr);
value = normalizeValue(attr, value, parentAttributes, fontSize);
if (value) { // eslint-disable-line
memo[attr] = value;
}
return memo;
}, { });
// add values parsed from style, which take precedence over attributes
// (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)
ownAttributes = extend(ownAttributes,
extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));
if (ownAttributes.font) {
fabric.parseFontDeclaration(ownAttributes.font, ownAttributes);
var normalizedAttr, normalizedValue, normalizedStyle = {};
for (var attr in ownAttributes) {
normalizedAttr = normalizeAttr(attr);
normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);
normalizedStyle[normalizedAttr] = normalizedValue;
}
return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes));
if (normalizedStyle && normalizedStyle.font) {
fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);
}
var mergedAttrs = extend(parentAttributes, normalizedStyle);
return reAllowedParents.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);
},
/**
@ -4085,8 +4096,8 @@ if (typeof console !== 'undefined') {
for (var i = 0, len = propertyValuePairs.length; i < len; i++) {
var pair = propertyValuePairs[i].split(/\s*:\s*/),
property = normalizeAttr(pair[0]),
value = normalizeValue(property, pair[1], pair[0]);
property = pair[0],
value = pair[1];
ruleObj[property] = value;
}
rule = match[1];
@ -10678,10 +10689,13 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
this._beforeTransform(e, target);
this._setupCurrentTransform(e, target);
}
if (target !== this.getActiveGroup() && target !== this.getActiveObject()) {
var activeObject = this.getActiveObject();
if (target !== this.getActiveGroup() && target !== activeObject) {
this.deactivateAll();
target.selectable && this.setActiveObject(target, e);
if (target.selectable) {
activeObject && activeObject.fire('deselected', { e: e });
this.setActiveObject(target, e);
}
}
}
this._handleEvent(e, 'down', target ? target : null);
@ -12414,8 +12428,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
width = dim.x * zoomX,
height = dim.y * zoomY;
return {
width: Math.ceil(width) + 2,
height: Math.ceil(height) + 2,
width: width + 2,
height: height + 2,
zoomX: zoomX,
zoomY: zoomY
};
@ -12439,8 +12453,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
zoomX = dims.zoomX, zoomY = dims.zoomY;
if (width !== this.cacheWidth || height !== this.cacheHeight) {
this._cacheCanvas.width = width;
this._cacheCanvas.height = height;
this._cacheCanvas.width = Math.ceil(width);
this._cacheCanvas.height = Math.ceil(height);
this._cacheContext.translate(width / 2, height / 2);
this._cacheContext.scale(zoomX, zoomY);
this.cacheWidth = width;
@ -13356,8 +13370,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
object = clone(object, true);
if (forceAsync) {
fabric.util.enlivenPatterns([object.fill, object.stroke], function(patterns) {
object.fill = patterns[0];
object.stroke = patterns[1];
if (typeof patterns[0] !== 'undefined') {
object.fill = patterns[0];
}
if (typeof patterns[1] !== 'undefined') {
object.stroke = patterns[1];
}
var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);
callback && callback(instance);
});
@ -15305,10 +15323,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
// Line coords are distances from left-top of canvas to origin of line.
// To render line in a path-group, we need to translate them to
// distances from center of path-group to center of line.
var cp = this.getCenterPoint();
var cp = this.getCenterPoint(),
offset = this.strokeWidth / 2;
ctx.translate(
cp.x - this.strokeWidth / 2,
cp.y - this.strokeWidth / 2
cp.x - (this.strokeLineCap === 'butt' && this.height === 0 ? 0 : offset),
cp.y - (this.strokeLineCap === 'butt' && this.width === 0 ? 0 : offset)
);
}
@ -15360,10 +15379,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
_getNonTransformedDimensions: function() {
var dim = this.callSuper('_getNonTransformedDimensions');
if (this.strokeLineCap === 'butt') {
if (dim.x === 0) {
if (this.width === 0) {
dim.y -= this.strokeWidth;
}
if (dim.y === 0) {
if (this.height === 0) {
dim.x -= this.strokeWidth;
}
}
@ -17897,7 +17916,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
var originalPaths = object.paths;
delete object.paths;
// remove this pattern from 2.0 accepts only object
if (typeof orignalPaths === 'string') {
if (typeof originalPaths === 'string') {
fabric.loadSVGFromURL(originalPaths, function (elements) {
var pathUrl = originalPaths;
var pathGroup = fabric.util.groupSVGElements(elements, object, pathUrl);
@ -21736,6 +21755,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
this.callSuper('initialize', options);
this.__skipDimension = false;
this._initDimensions();
this.setCoords();
this.setupState({ propertySet: '_dimensionAffectingProps' });
},
@ -21781,9 +21801,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
*/
_getCacheCanvasDimensions: function() {
var dim = this.callSuper('_getCacheCanvasDimensions');
var fontSize = Math.ceil(this.fontSize) * 2;
dim.width += fontSize;
dim.height += fontSize;
var fontSize = this.fontSize * 2;
dim.width += fontSize * dim.zoomX;
dim.height += fontSize * dim.zoomY;
return dim;
},
@ -23138,9 +23158,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
lineIndex = cursorLocation.lineIndex,
charIndex = cursorLocation.charIndex,
charHeight = this.getCurrentCharFontSize(lineIndex, charIndex),
leftOffset = (lineIndex === 0 && charIndex === 0)
? this._getLineLeftOffset(this._getLineWidth(ctx, lineIndex))
: boundaries.leftOffset,
leftOffset = boundaries.leftOffset,
multiplier = this.scaleX * this.canvas.getZoom(),
cursorWidth = this.cursorWidth / multiplier;
@ -24261,9 +24279,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
lineIndex = cursorLocation.lineIndex,
charIndex = cursorLocation.charIndex,
charHeight = this.getCurrentCharFontSize(lineIndex, charIndex),
leftOffset = (lineIndex === 0 && charIndex === 0)
? this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex))
: boundaries.leftOffset,
leftOffset = boundaries.leftOffset,
m = this.calcTransformMatrix(),
p = {
x: boundaries.left + leftOffset,
@ -24467,10 +24483,6 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
this.shiftLineStyles(lineIndex, +1);
if (!this.styles[lineIndex + 1]) {
this.styles[lineIndex + 1] = {};
}
var currentCharStyle = {},
newLineStyles = {};
@ -24480,21 +24492,24 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
// if there's nothing after cursor,
// we clone current char style onto the next (otherwise empty) line
if (isEndOfLine) {
if (isEndOfLine && currentCharStyle) {
newLineStyles[0] = clone(currentCharStyle);
this.styles[lineIndex + 1] = newLineStyles;
}
// otherwise we clone styles of all chars
// after cursor onto the next line, from the beginning
else {
var somethingAdded = false;
for (var index in this.styles[lineIndex]) {
if (parseInt(index, 10) >= charIndex) {
newLineStyles[parseInt(index, 10) - charIndex] = this.styles[lineIndex][index];
var numIndex = parseInt(index, 10);
if (numIndex >= charIndex) {
somethingAdded = true;
newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];
// remove lines from the previous line since they're on a new line now
delete this.styles[lineIndex][index];
}
}
this.styles[lineIndex + 1] = newLineStyles;
somethingAdded && (this.styles[lineIndex + 1] = newLineStyles);
}
this._forceClearCache = true;
},
@ -24528,9 +24543,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
}
}
}
this.styles[lineIndex][charIndex] =
style || clone(currentLineStyles[charIndex - 1]);
var newStyle = style || currentLineStyles[charIndex - 1];
newStyle && (this.styles[lineIndex][charIndex] = newStyle);
this._forceClearCache = true;
},
@ -26225,8 +26239,6 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
}
};
var clone = fabric.util.object.clone;
fabric.util.object.extend(fabric.Textbox.prototype, /** @lends fabric.IText.prototype */ {
/**
* @private
@ -26278,24 +26290,10 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
*/
shiftLineStyles: function(lineIndex, offset) {
// shift all line styles by 1 upward
var clonedStyles = clone(this.styles),
map = this._styleMap[lineIndex];
var map = this._styleMap[lineIndex];
// adjust line index
lineIndex = map.line;
for (var line in this.styles) {
var numericLine = parseInt(line, 10);
if (numericLine > lineIndex) {
this.styles[numericLine + offset] = clonedStyles[numericLine];
if (!clonedStyles[numericLine - offset]) {
delete this.styles[numericLine];
}
}
}
//TODO: evaluate if delete old style lines with offset -1
fabric.IText.prototype.shiftLineStyles.call(this, lineIndex, offset);
},
/**

18
dist/fabric.min.js vendored

File diff suppressed because one or more lines are too long

BIN
dist/fabric.min.js.gz vendored

Binary file not shown.

110
dist/fabric.require.js vendored
View file

@ -1760,7 +1760,8 @@ if (typeof console !== "undefined") {
"stroke-opacity": "strokeOpacity",
"stroke-width": "strokeWidth",
"text-decoration": "textDecoration",
"text-anchor": "originX"
"text-anchor": "originX",
opacity: "opacity"
}, colorAttributes = {
stroke: "strokeOpacity",
fill: "fillOpacity"
@ -1796,6 +1797,11 @@ if (typeof console !== "undefined") {
if (parentAttributes && parentAttributes.visible === false) {
value = false;
}
} else if (attr === "opacity") {
value = parseFloat(value);
if (parentAttributes && typeof parentAttributes.opacity !== "undefined") {
value *= parentAttributes.opacity;
}
} else if (attr === "originX") {
value = value === "start" ? "left" : value === "end" ? "right" : "center";
} else {
@ -1910,8 +1916,8 @@ if (typeof console !== "undefined") {
var attr, value;
style.replace(/;\s*$/, "").split(";").forEach(function(chunk) {
var pair = chunk.split(":");
attr = normalizeAttr(pair[0].trim().toLowerCase());
value = normalizeValue(attr, pair[1].trim());
attr = pair[0].trim().toLowerCase();
value = pair[1].trim();
oStyle[attr] = value;
});
}
@ -1921,8 +1927,8 @@ if (typeof console !== "undefined") {
if (typeof style[prop] === "undefined") {
continue;
}
attr = normalizeAttr(prop.toLowerCase());
value = normalizeValue(attr, style[prop]);
attr = prop.toLowerCase();
value = style[prop];
oStyle[attr] = value;
}
}
@ -2174,17 +2180,22 @@ if (typeof console !== "undefined") {
var ownAttributes = attributes.reduce(function(memo, attr) {
value = element.getAttribute(attr);
if (value) {
attr = normalizeAttr(attr);
value = normalizeValue(attr, value, parentAttributes, fontSize);
memo[attr] = value;
}
return memo;
}, {});
ownAttributes = extend(ownAttributes, extend(getGlobalStylesForElement(element, svgUid), fabric.parseStyleAttribute(element)));
if (ownAttributes.font) {
fabric.parseFontDeclaration(ownAttributes.font, ownAttributes);
var normalizedAttr, normalizedValue, normalizedStyle = {};
for (var attr in ownAttributes) {
normalizedAttr = normalizeAttr(attr);
normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize);
normalizedStyle[normalizedAttr] = normalizedValue;
}
return _setStrokeFillOpacity(extend(parentAttributes, ownAttributes));
if (normalizedStyle && normalizedStyle.font) {
fabric.parseFontDeclaration(normalizedStyle.font, normalizedStyle);
}
var mergedAttrs = extend(parentAttributes, normalizedStyle);
return reAllowedParents.test(element.nodeName) ? mergedAttrs : _setStrokeFillOpacity(mergedAttrs);
},
parseElements: function(elements, callback, options, reviver) {
new fabric.ElementsParser(elements, callback, options, reviver).parse();
@ -2233,7 +2244,7 @@ if (typeof console !== "undefined") {
rules.forEach(function(rule) {
var match = rule.match(/([\s\S]*?)\s*\{([^}]*)\}/), ruleObj = {}, declaration = match[2].trim(), propertyValuePairs = declaration.replace(/;$/, "").split(/\s*;\s*/);
for (var i = 0, len = propertyValuePairs.length; i < len; i++) {
var pair = propertyValuePairs[i].split(/\s*:\s*/), property = normalizeAttr(pair[0]), value = normalizeValue(property, pair[1], pair[0]);
var pair = propertyValuePairs[i].split(/\s*:\s*/), property = pair[0], value = pair[1];
ruleObj[property] = value;
}
rule = match[1];
@ -5430,9 +5441,15 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, {
this._beforeTransform(e, target);
this._setupCurrentTransform(e, target);
}
if (target !== this.getActiveGroup() && target !== this.getActiveObject()) {
var activeObject = this.getActiveObject();
if (target !== this.getActiveGroup() && target !== activeObject) {
this.deactivateAll();
target.selectable && this.setActiveObject(target, e);
if (target.selectable) {
activeObject && activeObject.fire("deselected", {
e: e
});
this.setActiveObject(target, e);
}
}
}
this._handleEvent(e, "down", target ? target : null);
@ -5986,8 +6003,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
_getCacheCanvasDimensions: function() {
var zoom = this.canvas && this.canvas.getZoom() || 1, objectScale = this.getObjectScaling(), dim = this._getNonTransformedDimensions(), retina = this.canvas && this.canvas._isRetinaScaling() ? fabric.devicePixelRatio : 1, zoomX = objectScale.scaleX * zoom * retina, zoomY = objectScale.scaleY * zoom * retina, width = dim.x * zoomX, height = dim.y * zoomY;
return {
width: Math.ceil(width) + 2,
height: Math.ceil(height) + 2,
width: width + 2,
height: height + 2,
zoomX: zoomX,
zoomY: zoomY
};
@ -6001,8 +6018,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
}
var dims = this._getCacheCanvasDimensions(), width = dims.width, height = dims.height, zoomX = dims.zoomX, zoomY = dims.zoomY;
if (width !== this.cacheWidth || height !== this.cacheHeight) {
this._cacheCanvas.width = width;
this._cacheCanvas.height = height;
this._cacheCanvas.width = Math.ceil(width);
this._cacheCanvas.height = Math.ceil(height);
this._cacheContext.translate(width / 2, height / 2);
this._cacheContext.scale(zoomX, zoomY);
this.cacheWidth = width;
@ -6474,8 +6491,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, {
object = clone(object, true);
if (forceAsync) {
fabric.util.enlivenPatterns([ object.fill, object.stroke ], function(patterns) {
object.fill = patterns[0];
object.stroke = patterns[1];
if (typeof patterns[0] !== "undefined") {
object.fill = patterns[0];
}
if (typeof patterns[1] !== "undefined") {
object.stroke = patterns[1];
}
var instance = extraParam ? new klass(object[extraParam], object) : new klass(object);
callback && callback(instance);
});
@ -7394,8 +7415,8 @@ fabric.util.object.extend(fabric.Object.prototype, {
_render: function(ctx, noTransform) {
ctx.beginPath();
if (noTransform) {
var cp = this.getCenterPoint();
ctx.translate(cp.x - this.strokeWidth / 2, cp.y - this.strokeWidth / 2);
var cp = this.getCenterPoint(), offset = this.strokeWidth / 2;
ctx.translate(cp.x - (this.strokeLineCap === "butt" && this.height === 0 ? 0 : offset), cp.y - (this.strokeLineCap === "butt" && this.width === 0 ? 0 : offset));
}
if (!this.strokeDashArray || this.strokeDashArray && supportsLineDash) {
var p = this.calcLinePoints();
@ -7420,10 +7441,10 @@ fabric.util.object.extend(fabric.Object.prototype, {
_getNonTransformedDimensions: function() {
var dim = this.callSuper("_getNonTransformedDimensions");
if (this.strokeLineCap === "butt") {
if (dim.x === 0) {
if (this.width === 0) {
dim.y -= this.strokeWidth;
}
if (dim.y === 0) {
if (this.height === 0) {
dim.x -= this.strokeWidth;
}
}
@ -8601,7 +8622,7 @@ fabric.util.object.extend(fabric.Object.prototype, {
fabric.PathGroup.fromObject = function(object, callback) {
var originalPaths = object.paths;
delete object.paths;
if (typeof orignalPaths === "string") {
if (typeof originalPaths === "string") {
fabric.loadSVGFromURL(originalPaths, function(elements) {
var pathUrl = originalPaths;
var pathGroup = fabric.util.groupSVGElements(elements, object, pathUrl);
@ -10160,6 +10181,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
this.callSuper("initialize", options);
this.__skipDimension = false;
this._initDimensions();
this.setCoords();
this.setupState({
propertySet: "_dimensionAffectingProps"
});
@ -10182,9 +10204,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
},
_getCacheCanvasDimensions: function() {
var dim = this.callSuper("_getCacheCanvasDimensions");
var fontSize = Math.ceil(this.fontSize) * 2;
dim.width += fontSize;
dim.height += fontSize;
var fontSize = this.fontSize * 2;
dim.width += fontSize * dim.zoomX;
dim.height += fontSize * dim.zoomY;
return dim;
},
_render: function(ctx) {
@ -10806,7 +10828,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
return this.cursorOffsetCache;
},
renderCursor: function(boundaries, ctx) {
var cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = lineIndex === 0 && charIndex === 0 ? this._getLineLeftOffset(this._getLineWidth(ctx, lineIndex)) : boundaries.leftOffset, multiplier = this.scaleX * this.canvas.getZoom(), cursorWidth = this.cursorWidth / multiplier;
var cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = boundaries.leftOffset, multiplier = this.scaleX * this.canvas.getZoom(), cursorWidth = this.cursorWidth / multiplier;
ctx.fillStyle = this.getCurrentCharColor(lineIndex, charIndex);
ctx.globalAlpha = this.__isMousedown ? 1 : this._currentCursorOpacity;
ctx.fillRect(boundaries.left + leftOffset - cursorWidth / 2, boundaries.top + boundaries.topOffset, cursorWidth, charHeight);
@ -11447,7 +11469,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
y: 1
};
}
var chars = this.text.split(""), boundaries = this._getCursorBoundaries(chars, "cursor"), cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = lineIndex === 0 && charIndex === 0 ? this._getLineLeftOffset(this._getLineWidth(this.ctx, lineIndex)) : boundaries.leftOffset, m = this.calcTransformMatrix(), p = {
var chars = this.text.split(""), boundaries = this._getCursorBoundaries(chars, "cursor"), cursorLocation = this.get2DCursorLocation(), lineIndex = cursorLocation.lineIndex, charIndex = cursorLocation.charIndex, charHeight = this.getCurrentCharFontSize(lineIndex, charIndex), leftOffset = boundaries.leftOffset, m = this.calcTransformMatrix(), p = {
x: boundaries.left + leftOffset,
y: boundaries.top + boundaries.topOffset + charHeight
}, upperCanvas = this.canvas.upperCanvasEl, maxWidth = upperCanvas.width - charHeight, maxHeight = upperCanvas.height - charHeight;
@ -11591,24 +11613,24 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
},
insertNewlineStyleObject: function(lineIndex, charIndex, isEndOfLine) {
this.shiftLineStyles(lineIndex, +1);
if (!this.styles[lineIndex + 1]) {
this.styles[lineIndex + 1] = {};
}
var currentCharStyle = {}, newLineStyles = {};
if (this.styles[lineIndex] && this.styles[lineIndex][charIndex - 1]) {
currentCharStyle = this.styles[lineIndex][charIndex - 1];
}
if (isEndOfLine) {
if (isEndOfLine && currentCharStyle) {
newLineStyles[0] = clone(currentCharStyle);
this.styles[lineIndex + 1] = newLineStyles;
} else {
var somethingAdded = false;
for (var index in this.styles[lineIndex]) {
if (parseInt(index, 10) >= charIndex) {
newLineStyles[parseInt(index, 10) - charIndex] = this.styles[lineIndex][index];
var numIndex = parseInt(index, 10);
if (numIndex >= charIndex) {
somethingAdded = true;
newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];
delete this.styles[lineIndex][index];
}
}
this.styles[lineIndex + 1] = newLineStyles;
somethingAdded && (this.styles[lineIndex + 1] = newLineStyles);
}
this._forceClearCache = true;
},
@ -11626,7 +11648,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
}
}
}
this.styles[lineIndex][charIndex] = style || clone(currentLineStyles[charIndex - 1]);
var newStyle = style || currentLineStyles[charIndex - 1];
newStyle && (this.styles[lineIndex][charIndex] = newStyle);
this._forceClearCache = true;
},
insertStyleObjects: function(_chars, isEndOfLine, styleObject) {
@ -12531,7 +12554,6 @@ fabric.util.object.extend(fabric.IText.prototype, {
}
}
};
var clone = fabric.util.object.clone;
fabric.util.object.extend(fabric.Textbox.prototype, {
_removeExtraneousStyles: function() {
for (var prop in this._styleMap) {
@ -12553,17 +12575,9 @@ fabric.util.object.extend(fabric.IText.prototype, {
fabric.IText.prototype.insertNewlineStyleObject.apply(this, [ lineIndex, charIndex, isEndOfLine ]);
},
shiftLineStyles: function(lineIndex, offset) {
var clonedStyles = clone(this.styles), map = this._styleMap[lineIndex];
var map = this._styleMap[lineIndex];
lineIndex = map.line;
for (var line in this.styles) {
var numericLine = parseInt(line, 10);
if (numericLine > lineIndex) {
this.styles[numericLine + offset] = clonedStyles[numericLine];
if (!clonedStyles[numericLine - offset]) {
delete this.styles[numericLine];
}
}
}
fabric.IText.prototype.shiftLineStyles.call(this, lineIndex, offset);
},
_getTextOnPreviousLine: function(lIndex) {
var textOnPreviousLine = this._textLines[lIndex - 1];

View file

@ -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": "1.7.6",
"version": "1.7.7",
"author": "Juriy Zaytsev <kangax@gmail.com>",
"contributors": [
{