fabric.js/test/unit/text.js
Blob 3b314d11cc Add strokeDashOffset and svg corresponding attribute (#5398)
* Add strokeDashOffset and svg corresponding attribute
2018-11-23 00:56:00 +01:00

755 lines
29 KiB
JavaScript

(function() {
QUnit.module('fabric.Text');
function createTextObject(text) {
return new fabric.Text(text || 'x');
}
var CHAR_WIDTH = 20;
var REFERENCE_TEXT_OBJECT = {
'version': fabric.version,
'type': 'text',
'originX': 'left',
'originY': 'top',
'left': 0,
'top': 0,
'width': CHAR_WIDTH,
'height': 45.2,
'fill': 'rgb(0,0,0)',
'stroke': null,
'strokeWidth': 1,
'strokeDashArray': null,
'strokeLineCap': 'butt',
'strokeDashOffset': 0,
'strokeLineJoin': 'miter',
'strokeMiterLimit': 4,
'scaleX': 1,
'scaleY': 1,
'angle': 0,
'flipX': false,
'flipY': false,
'opacity': 1,
'shadow': null,
'visible': true,
'clipTo': null,
'backgroundColor': '',
'text': 'x',
'fontSize': 40,
'fontWeight': 'normal',
'fontFamily': 'Times New Roman',
'fontStyle': 'normal',
'lineHeight': 1.16,
'underline': false,
'overline': false,
'linethrough': false,
'textAlign': 'left',
'textBackgroundColor': '',
'fillRule': 'nonzero',
'paintFirst': 'fill',
'globalCompositeOperation': 'source-over',
'skewX': 0,
'skewY': 0,
'transformMatrix': null,
'charSpacing': 0,
'styles': {}
};
QUnit.test('constructor', function(assert) {
assert.ok(fabric.Text);
var text = createTextObject();
assert.ok(text);
assert.ok(text instanceof fabric.Text);
assert.ok(text instanceof fabric.Object);
assert.equal(text.get('type'), 'text');
assert.equal(text.get('text'), 'x');
});
QUnit.test('toString', function(assert) {
var text = createTextObject();
assert.ok(typeof text.toString === 'function');
assert.equal(text.toString(), '#<fabric.Text (1): { "text": "x", "fontFamily": "Times New Roman" }>');
});
QUnit.test('_getFontDeclaration', function(assert) {
var text = createTextObject();
assert.ok(typeof text._getFontDeclaration === 'function', 'has a private method _getFontDeclaration');
var fontDecl = text._getFontDeclaration();
assert.ok(typeof fontDecl === 'string', 'it returns a string');
assert.equal(fontDecl, 'normal normal 40px "Times New Roman"');
text.fontFamily = '"Times New Roman"';
fontDecl = text._getFontDeclaration();
assert.equal(fontDecl, 'normal normal 40px "Times New Roman"');
text.fontFamily = '\'Times New Roman\'';
fontDecl = text._getFontDeclaration();
assert.equal(fontDecl, 'normal normal 40px \'Times New Roman\'');
});
fabric.Text.genericFonts.forEach(function(fontName) {
QUnit.test('_getFontDeclaration with genericFonts', function(assert) {
var text = createTextObject();
text.fontFamily = fontName;
var fontDecl = text._getFontDeclaration();
assert.equal(fontDecl, 'normal normal 40px ' + fontName, 'it does not quote ' + fontName);
text.fontFamily = fontName.toUpperCase();
var fontDecl = text._getFontDeclaration();
assert.equal(fontDecl, 'normal normal 40px ' + fontName.toUpperCase(), 'it uses a non case sensitive logic');
});
});
QUnit.test('toObject', function(assert) {
var text = createTextObject();
assert.ok(typeof text.toObject === 'function');
assert.deepEqual(text.toObject(), REFERENCE_TEXT_OBJECT);
});
QUnit.test('complexity', function(assert) {
var text = createTextObject();
assert.ok(typeof text.complexity === 'function');
assert.equal(text.complexity(), 1);
});
QUnit.test('set', function(assert) {
var text = createTextObject();
assert.ok(typeof text.set === 'function');
assert.equal(text.set('text', 'bar'), text, 'should be chainable');
text.set({ left: 1234, top: 2345, angle: 55 });
assert.equal(text.get('left'), 1234);
assert.equal(text.get('top'), 2345);
assert.equal(text.get('angle'), 55);
});
QUnit.test('lineHeight with single line', function(assert) {
var text = createTextObject();
text.text = 'text with one line';
text.lineHeight = 2;
text.initDimensions();
var height = text.height;
text.lineHeight = 0.5;
text.initDimensions();
var heightNew = text.height;
assert.equal(height, heightNew, 'text height does not change with one single line');
});
QUnit.test('lineHeight with multi line', function(assert) {
var text = createTextObject();
text.text = 'text with\ntwo lines';
text.lineHeight = 0.1;
text.initDimensions();
var height = text.height,
minimumHeight = text.fontSize * text._fontSizeMult;
assert.equal(height > minimumHeight, true, 'text height is always bigger than minimum Height');
});
QUnit.test('set with "hash"', function(assert) {
var text = createTextObject();
text.set({ opacity: 0.123, fill: 'red', fontFamily: 'blah' });
assert.equal(text.opacity, 0.123);
assert.equal(text.fill, 'red');
assert.equal(text.fontFamily, 'blah');
});
QUnit.test('get bounding rect after init', function(assert) {
var string = 'Some long text, the quick brown fox jumps over the lazy dog etc... blah blah blah';
var text = new fabric.Text(string, {
left: 30,
top: 30,
fill: '#ffffff',
fontSize: 24,
fontWeight: 'normal',
fontFamily: 'Arial',
originY: 'bottom'
});
var br = text.getBoundingRect();
text.setCoords();
var br2 = text.getBoundingRect();
assert.deepEqual(br, br2, 'text bounding box is the same before and after calling setCoords');
});
QUnit.test('setShadow', function(assert) {
var text = createTextObject();
assert.ok(typeof text.setShadow === 'function');
assert.equal(text.setShadow('10px 8px 2px red'), text, 'should be chainable');
assert.ok(text.shadow instanceof fabric.Shadow, 'should inherit from fabric.Shadow');
assert.equal(text.shadow.color, 'red');
assert.equal(text.shadow.offsetX, 10);
assert.equal(text.shadow.offsetY, 8);
assert.equal(text.shadow.blur, 2);
});
QUnit.test('fabric.Text.fromObject', function(assert) {
var done = assert.async();
assert.ok(typeof fabric.Text.fromObject === 'function');
fabric.Text.fromObject(REFERENCE_TEXT_OBJECT, function(text) {
assert.deepEqual(text.toObject(), REFERENCE_TEXT_OBJECT);
done();
});
});
QUnit.test('fabric.Text.fromElement', function(assert) {
assert.ok(typeof fabric.Text.fromElement === 'function');
var elText = fabric.document.createElement('text');
elText.textContent = 'x';
fabric.Text.fromElement(elText, function(text) {
assert.ok(text instanceof fabric.Text);
var expectedObject = fabric.util.object.extend(fabric.util.object.clone(REFERENCE_TEXT_OBJECT), {
left: 0,
top: -14.05,
width: 8,
height: 18.08,
fontSize: 16,
originX: 'left'
});
assert.deepEqual(text.toObject(), expectedObject, 'parsed object is what expected');
});
});
QUnit.test('fabric.Text.fromElement with custom attributes', function(assert) {
var elTextWithAttrs = fabric.document.createElement('text');
elTextWithAttrs.textContent = 'x';
elTextWithAttrs.setAttribute('x', 10);
elTextWithAttrs.setAttribute('y', 20);
elTextWithAttrs.setAttribute('fill', 'rgb(255,255,255)');
elTextWithAttrs.setAttribute('opacity', 0.45);
elTextWithAttrs.setAttribute('stroke', 'blue');
elTextWithAttrs.setAttribute('stroke-width', 3);
elTextWithAttrs.setAttribute('stroke-dasharray', '5, 2');
elTextWithAttrs.setAttribute('stroke-linecap', 'round');
elTextWithAttrs.setAttribute('stroke-linejoin', 'bevil');
elTextWithAttrs.setAttribute('stroke-miterlimit', 5);
elTextWithAttrs.setAttribute('font-family', 'Monaco');
elTextWithAttrs.setAttribute('font-style', 'italic');
elTextWithAttrs.setAttribute('font-weight', 'bold');
elTextWithAttrs.setAttribute('font-size', '123');
elTextWithAttrs.setAttribute('letter-spacing', '1em');
elTextWithAttrs.setAttribute('text-decoration', 'underline');
elTextWithAttrs.setAttribute('text-anchor', 'middle');
fabric.Text.fromElement(elTextWithAttrs, function(textWithAttrs) {
// temp workaround for text objects not obtaining width under node
textWithAttrs.width = CHAR_WIDTH;
assert.ok(textWithAttrs instanceof fabric.Text);
var expectedObject = fabric.util.object.extend(fabric.util.object.clone(REFERENCE_TEXT_OBJECT), {
/* left varies slightly due to node-canvas rendering */
left: fabric.util.toFixed(textWithAttrs.left + '', 2),
top: -88.03,
width: CHAR_WIDTH,
height: 138.99,
fill: 'rgb(255,255,255)',
opacity: 0.45,
stroke: 'blue',
strokeWidth: 3,
strokeDashArray: [5, 2],
strokeLineCap: 'round',
strokeLineJoin: 'bevil',
strokeMiterLimit: 5,
fontFamily: 'Monaco',
paintFirst: 'fill',
fontStyle: 'italic',
charSpacing: 1000,
fontWeight: 'bold',
fontSize: 123,
underline: true,
});
assert.deepEqual(textWithAttrs.toObject(), expectedObject);
});
});
QUnit.test('empty fromElement', function(assert) {
fabric.Text.fromElement(null, function(text) {
assert.equal(text, null);
});
});
QUnit.test('dimensions after text change', function(assert) {
var text = new fabric.Text('x');
assert.equal(text.width, CHAR_WIDTH);
text.set('text', 'xx');
assert.equal(text.width, CHAR_WIDTH * 2);
});
QUnit.test('dimensions without text', function(assert) {
var text = new fabric.Text('');
assert.equal(text.width, 2);
});
QUnit.test('setting fontFamily', function(assert) {
var text = new fabric.Text('x');
text.path = 'foobar.js';
text.set('fontFamily', 'foobar');
assert.equal(text.get('fontFamily'), 'foobar');
text.set('fontFamily', '"Arial Black", Arial');
assert.equal(text.get('fontFamily'), '"Arial Black", Arial');
});
QUnit.test('text styleHas', function(assert) {
var text = new fabric.Text('xxxxxx\nx y');
text.styles = { };
assert.ok(typeof text.styleHas === 'function');
assert.equal(text.styleHas('stroke'), false, 'the text style has no stroke');
text.styles = { 1: { 0: { stroke: 'red' }}};
assert.equal(text.styleHas('stroke'), true, 'the text style has stroke');
});
QUnit.test('text cleanStyle', function(assert) {
var text = new fabric.Text('xxxxxx\nx y');
text.styles = { 1: { 0: { stroke: 'red' }}};
text.stroke = 'red';
assert.ok(typeof text.cleanStyle === 'function');
text.cleanStyle('stroke');
assert.equal(text.styles[1], undefined, 'the style has been cleaned since stroke was equal to text property');
text.styles = { 1: { 0: { stroke: 'blue' }}};
text.stroke = 'red';
text.cleanStyle('stroke');
assert.equal(text.styles[1][0].stroke, 'blue', 'nothing to clean, style untouched');
});
QUnit.test('text cleanStyle with different sub styles styles', function(assert) {
var text = new fabric.Text('xxxxxx\nx y');
text.styles = { 1: { 0: { fill: 'red' }, 1: { stroke: 'red' }, 2: { stroke: 'blue' }}};
text.stroke = 'red';
text.cleanStyle('stroke');
assert.equal(text.stroke, 'red', 'the stroke stays red');
assert.equal(text.styles[1][0].fill, 'red', 'the style has not been changed since it\'s a different property');
assert.equal(text.styles[1][0].stroke, undefined, 'the style has been cleaned since stroke was equal to text property');
assert.equal(text.styles[1][1], undefined, 'the style remains undefined');
assert.equal(text.styles[1][2].stroke, 'blue', 'the style remains unchanged');
});
QUnit.test('text cleanStyle with undefined and set styles', function(assert) {
var text = new fabric.Text('xxxxxx\nx y');
text.styles = { 1: { 1: { stroke: 'red' }, 3: { stroke: 'red' }}};
text.stroke = 'red';
text.cleanStyle('stroke');
assert.equal(text.stroke, 'red', 'the stroke stays red');
assert.equal(text.styles[1], undefined, 'the style has been cleaned since stroke was equal to text property');
});
QUnit.test('text cleanStyle with empty styles', function(assert) {
var text = new fabric.Text('xxxxxx\nx y');
text.styles = { 1: { 0: { }, 1: { }}, 2: { }, 3: { 4: { }}};
text.cleanStyle('any');
assert.equal(text.styles[1], undefined, 'the style has been cleaned since there were no usefull informations');
assert.equal(text.styles[2], undefined, 'the style has been cleaned since there were no usefull informations');
assert.equal(text.styles[3], undefined, 'the style has been cleaned since there were no usefull informations');
});
QUnit.test('text cleanStyle with full style', function(assert) {
var text = new fabric.Text('xxx');
text.styles = { 0: { 0: { fill: 'blue' }, 1: { fill: 'blue' }, 2: { fill: 'blue' }}};
text.fill = 'black';
text.cleanStyle('fill');
assert.equal(text.fill, 'blue', 'the fill has been changed to blue');
assert.equal(text.styles[0], undefined, 'all the style has been removed');
});
QUnit.test('text cleanStyle with no relevant style', function(assert) {
var text = new fabric.Text('xxx');
text.styles = { 0: { 0: { other: 'value1' }, 1: { other: 'value2' }, 2: { other: 'value3' }}};
text.fill = 'black';
text.cleanStyle('fill');
assert.equal(text.fill, 'black', 'the fill remains black');
assert.equal(text.styles[0][0].other, 'value1', 'style remains the same');
assert.equal(text.styles[0][0].full, undefined, 'style remains undefined');
assert.equal(text.styles[0][1].other, 'value2', 'style remains the same');
assert.equal(text.styles[0][1].full, undefined, 'style remains undefined');
assert.equal(text.styles[0][2].other, 'value3', 'style remains the same');
assert.equal(text.styles[0][2].full, undefined, 'style remains undefined');
});
QUnit.test('text removeStyle with some style', function(assert) {
var text = new fabric.Text('xxx');
text.styles = { 0: { 0: { stroke: 'black', fill: 'blue' }, 1: { fill: 'blue' }, 2: { fill: 'blue' }}};
assert.ok(typeof text.removeStyle === 'function');
text.fill = 'red';
text.removeStyle('fill');
assert.equal(text.fill, 'red', 'the fill has not been changed');
assert.equal(text.styles[0][0].stroke, 'black', 'the non fill part of the style is still there');
assert.equal(text.styles[0][0].fill, undefined, 'the fill part of the style has been removed');
text.styles = { 0: { 0: { fill: 'blue' }, 1: { fill: 'blue' }, 2: { fill: 'blue' }}};
text.removeStyle('fill');
assert.equal(text.styles[0], undefined, 'the styles got empty and has been removed');
});
QUnit.test('getFontCache works with fontWeight numbers', function(assert) {
var text = new fabric.Text('xxx', { fontWeight: 400 });
text.initDimensions();
var cache = fabric.charWidthsCache[text.fontFamily.toLowerCase()];
var cacheProp = text.fontStyle + '_400';
assert.equal(cacheProp in cache, true, '400 is converted to string');
});
QUnit.test('getFontCache is case insensitive', function(assert) {
var text = new fabric.Text('xxx', { fontWeight: 'BOld', fontStyle: 'NormaL' });
text.initDimensions();
var text2 = new fabric.Text('xxx', { fontWeight: 'bOLd', fontStyle: 'nORMAl' });
text2.initDimensions();
var cache = text.getFontCache(text);
var cache2 = text2.getFontCache(text2);
assert.equal(cache, cache2, 'you get the same cache');
});
// moved
QUnit.test('getSelectionStyles with no arguments', function(assert) {
var iText = new fabric.Text('test foo bar-baz\nqux', {
styles: {
0: {
0: { textDecoration: 'underline' },
2: { textDecoration: 'overline' },
4: { textBackgroundColor: '#ffc' }
},
1: {
0: { fill: 'red' },
1: { fill: 'green' },
2: { fill: 'blue' }
}
}
});
assert.equal(typeof iText.getSelectionStyles, 'function');
assert.deepEqual(iText.getSelectionStyles(), []);
});
QUnit.test('getSelectionStyles with 2 args', function(assert) {
var iText = new fabric.Text('test foo bar-baz\nqux', {
styles: {
0: {
0: { textDecoration: 'underline' },
2: { textDecoration: 'overline' },
4: { textBackgroundColor: '#ffc' }
},
1: {
0: { fill: 'red' },
1: { fill: 'green' },
2: { fill: 'blue' }
}
}
});
assert.deepEqual(iText.getSelectionStyles(0, 5), [
{ textDecoration: 'underline' },
{},
{ textDecoration: 'overline' },
{},
{ textBackgroundColor: '#ffc' },
]);
assert.deepEqual(iText.getSelectionStyles(2, 2), [
]);
});
QUnit.test('setSelectionStyles', function(assert) {
var iText = new fabric.Text('test foo bar-baz\nqux', {
styles: {
0: {
0: { fill: '#112233' },
2: { stroke: '#223344' }
}
}
});
assert.equal(typeof iText.setSelectionStyles, 'function');
iText.setSelectionStyles({
fill: 'red',
stroke: 'yellow'
});
assert.deepEqual(iText.styles[0][0], {
fill: '#112233'
});
iText.setSelectionStyles({
fill: 'red',
stroke: 'yellow'
}, 0, 1);
assert.deepEqual(iText.styles[0][0], {
fill: 'red',
stroke: 'yellow'
});
iText.setSelectionStyles({
fill: '#998877',
stroke: 'yellow'
}, 2, 3);
assert.deepEqual(iText.styles[0][2], {
fill: '#998877',
stroke: 'yellow'
});
});
QUnit.test('getStyleAtPosition', function(assert) {
var iText = new fabric.Text('test foo bar-baz\nqux', {
styles: {
0: {
0: { textDecoration: 'underline' },
2: { textDecoration: 'overline' },
4: { textBackgroundColor: '#ffc' }
},
1: {
0: { fill: 'red' },
1: { fill: 'green' },
2: { fill: 'blue' }
}
}
});
assert.equal(typeof iText.getStyleAtPosition, 'function');
assert.deepEqual(iText.getStyleAtPosition(2), { textDecoration: 'overline' });
assert.deepEqual(iText.getStyleAtPosition(1), { });
assert.deepEqual(iText.getStyleAtPosition(18), { fill: 'green' });
});
QUnit.test('_splitText', function(assert) {
var text = new fabric.Text('test foo bar-baz\nqux', {});
var test = text._splitText();
assert.equal(test.lines[0], 'test foo bar-baz', 'first line is correct');
assert.equal(test.lines[1], 'qux', 'second line is correct');
assert.deepEqual(test.graphemeLines[0], ['t','e','s','t',' ','f','o','o',' ','b','a','r','-','b','a','z'], 'first line is correct');
assert.deepEqual(test.graphemeLines[1], ['q','u','x'], 'second line is correct');
});
QUnit.test('getStyleAtPosition complete', function(assert) {
var iText = new fabric.Text('test foo bar-baz\nqux', {
styles: {
0: {
0: { underline: true },
2: { overline: true },
4: { textBackgroundColor: '#ffc' }
},
1: {
0: { fill: 'red' },
1: { fill: 'green' },
2: { fill: 'blue' }
}
}
});
var expectedStyle0 = {
stroke: null,
strokeWidth: 1,
fill: 'rgb(0,0,0)',
fontFamily: 'Times New Roman',
fontSize: 40,
fontWeight: 'normal',
fontStyle: 'normal',
underline: true,
overline: false,
linethrough: false,
textBackgroundColor: '',
deltaY: 0,
};
var expectedStyle2 = {
stroke: null,
strokeWidth: 1,
fill: 'rgb(0,0,0)',
fontFamily: 'Times New Roman',
fontSize: 40,
fontWeight: 'normal',
fontStyle: 'normal',
underline: false,
overline: true,
linethrough: false,
textBackgroundColor: '',
deltaY: 0,
};
assert.equal(typeof iText.getStyleAtPosition, 'function');
assert.deepEqual(iText.getStyleAtPosition(0, true), expectedStyle0, 'styles do match at 0');
assert.deepEqual(iText.getStyleAtPosition(2, true), expectedStyle2, 'styles do match at 2');
});
QUnit.test('toSVG with NUM_FRACTION_DIGITS', function(assert) {
var iText = new fabric.IText('test foo bar-baz', {
// makes weird numbers
styles: {
0: {
0: {
fill: 'red',
},
1: {
fill: 'blue',
},
2: {
fill: 'green',
},
3: {
fill: 'yellow',
},
4: {
fill: 'pink',
},
}
}
});
fabric.Object.NUM_FRACTION_DIGITS = 1;
var SVG_1 = iText.toSVG();
// var SVG_1_EXPECTED = '\t<g transform="translate(124.5 23.1)">\n\t\t<text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;" ><tspan x="-124" y="12.6" style="fill: rgb(255,0,0); ">t</tspan><tspan x="-112.9" y="12.6" style="fill: rgb(0,0,255); ">e</tspan><tspan x="-95.1" y="12.6" style="fill: rgb(0,128,0); ">s</tspan><tspan x="-79.6" y="12.6" style="fill: rgb(255,255,0); ">t</tspan><tspan x="-68.4" y="12.6" style="fill: rgb(255,192,203); white-space: pre; "> </tspan><tspan x="-58.4" y="12.6" >foo bar-baz</tspan></text>\n\t</g>\n';
//assert.equal(SVG_1, SVG_1_EXPECTED, 'numbers have max 1 decimal');
fabric.Object.NUM_FRACTION_DIGITS = 3;
var SVG_2 = iText.toSVG();
// var SVG_2_EXPECTED = '\t<g transform="translate(124.484 23.1)">\n\t\t<text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; white-space: pre;" ><tspan x="-123.984" y="12.566" style="fill: rgb(255,0,0); ">t</tspan><tspan x="-112.871" y="12.566" style="fill: rgb(0,0,255); ">e</tspan><tspan x="-95.117" y="12.566" style="fill: rgb(0,128,0); ">s</tspan><tspan x="-79.551" y="12.566" style="fill: rgb(255,255,0); ">t</tspan><tspan x="-68.438" y="12.566" style="fill: rgb(255,192,203); white-space: pre; "> </tspan><tspan x="-58.438" y="12.566" >foo bar-baz</tspan></text>\n\t</g>\n';
//assert.equal(SVG_2, SVG_2_EXPECTED, 'numbers have max 3 decimal');
assert.ok(SVG_2.length > SVG_1.length, 'SVG 2 has more decimal');
// put back to 2 or break all tests
fabric.Object.NUM_FRACTION_DIGITS = 2;
});
QUnit.test('getSvgSpanStyles produces correct output', function(assert) {
var iText = new fabric.IText('test foo bar-baz');
var styleObject = {
fill: 'red',
strokeWidth: 30,
fontFamily: 'Verdana',
fontSize: 25,
};
var styleString = iText.getSvgSpanStyles(styleObject);
var expected = 'stroke-width: 30; font-family: \'Verdana\'; font-size: 25px; fill: rgb(255,0,0); ';
assert.equal(styleString, expected, 'style is as expected');
});
QUnit.test('getSvgSpanStyles produces correct output with useWhiteSpace', function(assert) {
var iText = new fabric.IText('test foo bar-baz');
var styleObject = {
fill: 'red',
strokeWidth: 30,
fontFamily: 'Verdana',
fontSize: 25,
};
var styleString = iText.getSvgSpanStyles(styleObject, true);
var expected = 'stroke-width: 30; font-family: \'Verdana\'; font-size: 25px; fill: rgb(255,0,0); white-space: pre; ';
assert.equal(styleString, expected, 'style is as expected');
});
QUnit.test('getSvgTextDecoration with overline true produces correct output', function(assert){
var iText = new fabric.IText('test foo bar-baz');
var styleObject = {
overline: true,
};
var styleString = iText.getSvgTextDecoration(styleObject);
var expected = 'overline ';
assert.equal(styleString, expected, 'style is as expected');
});
QUnit.test('getSvgTextDecoration with overline underline true produces correct output', function(assert){
var iText = new fabric.IText('test foo bar-baz');
var styleObject = {
overline: true,
underline: true,
};
var styleString = iText.getSvgTextDecoration(styleObject);
var expected = 'overline underline ';
assert.equal(styleString, expected, 'style is as expected with overline underline');
});
QUnit.test('getSvgTextDecoration with overline underline true produces correct output', function(assert){
var iText = new fabric.IText('test foo bar-baz');
var styleObject = {
overline: true,
underline: true,
linethrough: true,
};
var styleString = iText.getSvgTextDecoration(styleObject);
var expected = 'overline underline line-through ';
assert.equal(styleString, expected, 'style is as expected with overline underline');
});
QUnit.test('getSvgTextDecoration with overline underline true produces correct output', function(assert){
var iText = new fabric.IText('test foo bar-baz');
var styleObject = {
overline: true,
underline: true,
linethrough: true,
};
var styleString = iText.getSvgTextDecoration(styleObject);
var expected = 'overline underline line-through ';
assert.equal(styleString, expected, 'style is as expected with overline underline');
});
QUnit.test('text superscript', function(assert) {
var text = new fabric.Text('xxx', { styles: {
0: { 0: { stroke: 'black', fill: 'blue' }, 1: { fill: 'blue' }, 2: { fontSize: 4, deltaY: 20 }}
} });
assert.ok(typeof text.setSuperscript === 'function');
var size = text.fontSize;
var schema = text.superscript;
var styleFontSize = text.styles[0][2].fontSize;
var styleDeltaY = text.styles[0][2].deltaY;
text.setSuperscript(1, 2).setSuperscript(2, 3);
assert.equal(text.styles[0][0].fontSize, undefined, 'character 0: fontSize is not set');
assert.equal(text.styles[0][0].deltaY, undefined, 'character 0: deltaY is not set');
assert.equal(text.styles[0][1].fontSize, size * schema.size, 'character 1: fontSize has been set');
assert.equal(text.styles[0][1].deltaY, size * schema.baseline, 'character 1: deltaY has been set');
assert.equal(text.styles[0][2].fontSize, styleFontSize * schema.size, 'character 2: fontSize has been decreased');
assert.equal(text.styles[0][2].deltaY, styleDeltaY + styleFontSize * schema.baseline, 'character 2: deltaY has been decreased');
});
QUnit.test('text subscript', function(assert) {
var text = new fabric.Text('xxx', { styles: {
0: { 0: { stroke: 'black', fill: 'blue' }, 1: { fill: 'blue' }, 2: { fontSize: 4, deltaY: 20 }}
} });
assert.ok(typeof text.setSubscript === 'function');
var size = text.fontSize;
var schema = text.subscript;
var styleFontSize = text.styles[0][2].fontSize;
var styleDeltaY = text.styles[0][2].deltaY;
text.setSubscript(1,2).setSubscript(2,3);
assert.equal(text.styles[0][0].fontSize, undefined, 'character 0: fontSize is not set');
assert.equal(text.styles[0][0].deltaY, undefined, 'character 0: deltaY is not set');
assert.equal(text.styles[0][1].fontSize, size * schema.size, 'character 1: fontSize has been set');
assert.equal(text.styles[0][1].deltaY, size * schema.baseline, 'character 1: deltaY has been set');
assert.equal(text.styles[0][2].fontSize, styleFontSize * schema.size, 'character 2: fontSize has been decreased');
assert.equal(text.styles[0][2].deltaY, styleDeltaY + styleFontSize * schema.baseline, 'character 2: deltaY has been increased');
});
QUnit.test('getHeightOfLine measures height of aline', function(assert) {
var text = new fabric.Text('xxx\n');
var height1 = text.getHeightOfLine(0);
var height2 = text.getHeightOfLine(1);
assert.equal(Math.round(height1), 52, 'height of line with text is ok');
assert.equal(Math.round(height2), 52, 'height of empty line is ok');
assert.equal(height1, height2, 'should have same height');
});
QUnit.test('_measureChar handles 0 width chars', function(assert) {
fabric.charWidthsCache = {};
var zwc = '\u200b';
var text = new fabric.Text('');
var style = text.getCompleteStyleDeclaration(0, 0);
var box = text._measureChar('a', style, zwc, style);
var box2 = text._measureChar('a', style, zwc, style);
assert.equal(fabric.charWidthsCache[text.fontFamily.toLowerCase()].normal_normal[zwc], 0, 'zwc is a 0 width char');
assert.equal(box.kernedWidth, box2.kernedWidth, '2 measurements of the same string return the same number');
});
})();