mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-24 21:23:44 +00:00
Add support for parsing shorthand font declaration in styles, such as "font: italic 12px Arial,Helvetica,sans-serif"
This commit is contained in:
parent
0229df4a78
commit
c65b1f5e7d
6 changed files with 136 additions and 53 deletions
|
|
@ -1,4 +1,4 @@
|
|||
### Fabric
|
||||
### Fabric
|
||||
[](http://travis-ci.org/#!/kangax/fabric.js)
|
||||
<a href="https://npmjs.org/package/fabric"><img src="https://badge.fury.io/js/fabric.png"></a>
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ Using Fabric.js, you can create and populate objects on canvas; objects like sim
|
|||
|
||||
### Goals
|
||||
|
||||
- Unit tested (1500+ tests at the moment)
|
||||
- Unit tested (1570+ tests at the moment)
|
||||
- Modular (~40 small "classes", modules, mixins)
|
||||
- Cross-browser
|
||||
- [Fast](https://github.com/kangax/fabric.js/wiki/Focus-on-speed)
|
||||
|
|
|
|||
109
dist/all.js
vendored
109
dist/all.js
vendored
|
|
@ -4182,6 +4182,34 @@ fabric.util.string = {
|
|||
return parsedPoints;
|
||||
}
|
||||
|
||||
function parseFontDeclaration(value, oStyle) {
|
||||
|
||||
// TODO: support non-px font size
|
||||
var match = value.match(/(normal|italic)?\s*(normal|small-caps)?\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\s*(\d+)px\s+(.*)/);
|
||||
|
||||
if (!match) return;
|
||||
|
||||
var fontStyle = match[1];
|
||||
// Font variant is not used
|
||||
// var fontVariant = match[2];
|
||||
var fontWeight = match[3];
|
||||
var fontSize = match[4];
|
||||
var fontFamily = match[5];
|
||||
|
||||
if (fontStyle) {
|
||||
oStyle.fontStyle = fontStyle;
|
||||
}
|
||||
if (fontWeight) {
|
||||
oStyle.fontSize = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);
|
||||
}
|
||||
if (fontSize) {
|
||||
oStyle.fontSize = parseFloat(fontSize);
|
||||
}
|
||||
if (fontFamily) {
|
||||
oStyle.fontFamily = fontFamily;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses "style" attribute, retuning an object with values
|
||||
* @static
|
||||
|
|
@ -4196,16 +4224,20 @@ fabric.util.string = {
|
|||
if (!style) return oStyle;
|
||||
|
||||
if (typeof style === 'string') {
|
||||
style = style.replace(/;$/, '').split(';').forEach(function (current) {
|
||||
style.replace(/;$/, '').split(';').forEach(function (chunk) {
|
||||
|
||||
var pair = current.split(':');
|
||||
var pair = chunk.split(':');
|
||||
var attr = normalizeAttr(pair[0].trim().toLowerCase());
|
||||
var value = normalizeValue(attr, pair[1].trim());
|
||||
|
||||
// TODO: need to normalize em, %, pt, etc. to px (!)
|
||||
var parsed = parseFloat(value);
|
||||
|
||||
oStyle[attr] = isNaN(parsed) ? value : parsed;
|
||||
if (attr === 'font') {
|
||||
parseFontDeclaration(value, oStyle);
|
||||
}
|
||||
else {
|
||||
// TODO: need to normalize em, %, pt, etc. to px (!)
|
||||
var parsed = parseFloat(value);
|
||||
oStyle[attr] = isNaN(parsed) ? value : parsed;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
|
@ -4214,9 +4246,15 @@ fabric.util.string = {
|
|||
|
||||
var attr = normalizeAttr(prop.toLowerCase());
|
||||
var value = normalizeValue(attr, style[prop]);
|
||||
var parsed = parseFloat(value);
|
||||
|
||||
oStyle[attr] = isNaN(parsed) ? value : parsed;
|
||||
if (attr === 'font') {
|
||||
parseFontDeclaration(value, oStyle);
|
||||
}
|
||||
else {
|
||||
// TODO: need to normalize em, %, pt, etc. to px (!)
|
||||
var parsed = parseFloat(value);
|
||||
oStyle[attr] = isNaN(parsed) ? value : parsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8845,6 +8883,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} e Event object fired on mousedown
|
||||
*/
|
||||
_onMouseDown: function (e) {
|
||||
this.__onMouseDown(e);
|
||||
|
|
@ -8861,6 +8900,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} e Event object fired on mouseup
|
||||
*/
|
||||
_onMouseUp: function (e) {
|
||||
this.__onMouseUp(e);
|
||||
|
|
@ -8877,6 +8917,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} e Event object fired on mousemove
|
||||
*/
|
||||
_onMouseMove: function (e) {
|
||||
e.preventDefault && e.preventDefault();
|
||||
|
|
@ -8969,7 +9010,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
* canvas so the current image can be placed on the top canvas and the rest
|
||||
* in on the container one.
|
||||
* @private
|
||||
* @param e {Event} Event object fired on mousedown
|
||||
* @param {Event} e Event object fired on mousedown
|
||||
*/
|
||||
__onMouseDown: function (e) {
|
||||
|
||||
|
|
@ -9004,6 +9045,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
this.deactivateAllWithDispatch();
|
||||
target && target.selectable && this.setActiveObject(target, e);
|
||||
}
|
||||
else if (this._shouldHandleGroupLogic(e, target)) {
|
||||
this._handleGroupLogic(e, target);
|
||||
target = this.getActiveGroup();
|
||||
}
|
||||
else {
|
||||
// determine if it's a drag or rotate case
|
||||
this.stateful && target.saveState();
|
||||
|
|
@ -9012,15 +9057,9 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
this.onBeforeScaleRotate(target);
|
||||
}
|
||||
|
||||
if (this._shouldHandleGroupLogic(e, target)) {
|
||||
this._handleGroupLogic(e, target);
|
||||
target = this.getActiveGroup();
|
||||
}
|
||||
else {
|
||||
if (target !== this.getActiveGroup() && target !== this.getActiveObject()) {
|
||||
this.deactivateAll();
|
||||
this.setActiveObject(target, e);
|
||||
}
|
||||
if (target !== this.getActiveGroup() && target !== this.getActiveObject()) {
|
||||
this.deactivateAll();
|
||||
this.setActiveObject(target, e);
|
||||
}
|
||||
|
||||
this._setupCurrentTransform(e, target);
|
||||
|
|
@ -9047,7 +9086,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
* all any other type of action.
|
||||
* In case of an image transformation only the top canvas will be rendered.
|
||||
* @private
|
||||
* @param e {Event} Event object fired on mousemove
|
||||
* @param {Event} e Event object fired on mousemove
|
||||
*/
|
||||
__onMouseMove: function (e) {
|
||||
|
||||
|
|
@ -9174,8 +9213,8 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|||
/**
|
||||
* Sets the cursor depending on where the canvas is being hovered.
|
||||
* Note: very buggy in Opera
|
||||
* @param e {Event} Event object
|
||||
* @param target {Object} Object that the mouse is hovering, if so.
|
||||
* @param {Event} e Event object
|
||||
* @param {Object} target Object that the mouse is hovering, if so.
|
||||
*/
|
||||
_setCursorFromEvent: function (e, target) {
|
||||
var s = this.upperCanvasEl.style;
|
||||
|
|
@ -15269,23 +15308,17 @@ fabric.Image.filters.Grayscale = fabric.util.createClass( /** @lends fabric.Imag
|
|||
var context = canvasEl.getContext('2d'),
|
||||
imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
|
||||
data = imageData.data,
|
||||
iLen = imageData.width,
|
||||
jLen = imageData.height,
|
||||
index, average, i, j;
|
||||
|
||||
for (i = 0; i < iLen; i++) {
|
||||
for (j = 0; j < jLen; j++) {
|
||||
|
||||
index = (i * 4) * jLen + (j * 4);
|
||||
average = (data[index] + data[index + 1] + data[index + 2]) / 3;
|
||||
|
||||
data[index] = average;
|
||||
data[index + 1] = average;
|
||||
data[index + 2] = average;
|
||||
}
|
||||
}
|
||||
|
||||
context.putImageData(imageData, 0, 0);
|
||||
len = imageData.width * imageData.height * 4,
|
||||
index = 0,
|
||||
average;
|
||||
while (index < len) {
|
||||
average = (data[index] + data[index + 1] + data[index + 2]) / 3;
|
||||
data[index] = average;
|
||||
data[index + 1] = average;
|
||||
data[index + 2] = average;
|
||||
index += 4;
|
||||
}
|
||||
context.putImageData(imageData, 0, 0);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
10
dist/all.min.js
vendored
10
dist/all.min.js
vendored
File diff suppressed because one or more lines are too long
BIN
dist/all.min.js.gz
vendored
BIN
dist/all.min.js.gz
vendored
Binary file not shown.
|
|
@ -287,6 +287,34 @@
|
|||
return parsedPoints;
|
||||
}
|
||||
|
||||
function parseFontDeclaration(value, oStyle) {
|
||||
|
||||
// TODO: support non-px font size
|
||||
var match = value.match(/(normal|italic)?\s*(normal|small-caps)?\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\s*(\d+)px\s+(.*)/);
|
||||
|
||||
if (!match) return;
|
||||
|
||||
var fontStyle = match[1];
|
||||
// Font variant is not used
|
||||
// var fontVariant = match[2];
|
||||
var fontWeight = match[3];
|
||||
var fontSize = match[4];
|
||||
var fontFamily = match[5];
|
||||
|
||||
if (fontStyle) {
|
||||
oStyle.fontStyle = fontStyle;
|
||||
}
|
||||
if (fontWeight) {
|
||||
oStyle.fontSize = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight);
|
||||
}
|
||||
if (fontSize) {
|
||||
oStyle.fontSize = parseFloat(fontSize);
|
||||
}
|
||||
if (fontFamily) {
|
||||
oStyle.fontFamily = fontFamily;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses "style" attribute, retuning an object with values
|
||||
* @static
|
||||
|
|
@ -301,16 +329,20 @@
|
|||
if (!style) return oStyle;
|
||||
|
||||
if (typeof style === 'string') {
|
||||
style = style.replace(/;$/, '').split(';').forEach(function (current) {
|
||||
style.replace(/;$/, '').split(';').forEach(function (chunk) {
|
||||
|
||||
var pair = current.split(':');
|
||||
var pair = chunk.split(':');
|
||||
var attr = normalizeAttr(pair[0].trim().toLowerCase());
|
||||
var value = normalizeValue(attr, pair[1].trim());
|
||||
|
||||
// TODO: need to normalize em, %, pt, etc. to px (!)
|
||||
var parsed = parseFloat(value);
|
||||
|
||||
oStyle[attr] = isNaN(parsed) ? value : parsed;
|
||||
if (attr === 'font') {
|
||||
parseFontDeclaration(value, oStyle);
|
||||
}
|
||||
else {
|
||||
// TODO: need to normalize em, %, pt, etc. to px (!)
|
||||
var parsed = parseFloat(value);
|
||||
oStyle[attr] = isNaN(parsed) ? value : parsed;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
|
|
@ -319,9 +351,15 @@
|
|||
|
||||
var attr = normalizeAttr(prop.toLowerCase());
|
||||
var value = normalizeValue(attr, style[prop]);
|
||||
var parsed = parseFloat(value);
|
||||
|
||||
oStyle[attr] = isNaN(parsed) ? value : parsed;
|
||||
if (attr === 'font') {
|
||||
parseFontDeclaration(value, oStyle);
|
||||
}
|
||||
else {
|
||||
// TODO: need to normalize em, %, pt, etc. to px (!)
|
||||
var parsed = parseFloat(value);
|
||||
oStyle[attr] = isNaN(parsed) ? value : parsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,6 +155,18 @@
|
|||
deepEqual(expectedObject, fabric.parseStyleAttribute(element));
|
||||
});
|
||||
|
||||
test('parseStyleAttribute with short font declaration', function() {
|
||||
var element = fabric.document.createElement('path');
|
||||
element.setAttribute('style', 'font: italic 12px Arial,Helvetica,sans-serif');
|
||||
|
||||
var expectedObject = {
|
||||
'fontSize': 12,
|
||||
'fontStyle': 'italic',
|
||||
'fontFamily': 'Arial,Helvetica,sans-serif'
|
||||
};
|
||||
deepEqual(expectedObject, fabric.parseStyleAttribute(element));
|
||||
});
|
||||
|
||||
test('parseAttributes (style to have higher priority than attribute)', function() {
|
||||
var element = fabric.document.createElement('path');
|
||||
element.setAttribute('style', 'fill:red');
|
||||
|
|
|
|||
Loading…
Reference in a new issue