mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
Merge branch 'kerning' of https://github.com/EugeneSqr/konva into EugeneSqr-kerning
This commit is contained in:
commit
fd4b1aab45
39
konva.js
39
konva.js
@ -16598,6 +16598,7 @@
|
||||
* @param {String} [config.fontVariant] can be normal or small-caps. Default is normal
|
||||
* @param {String} config.text
|
||||
* @param {String} config.data SVG data string
|
||||
* @param {Function} config.getKerning a getter for kerning values for the specified characters
|
||||
* @param {String} [config.fill] fill color
|
||||
* @param {Image} [config.fillPatternImage] fill pattern image
|
||||
* @param {Number} [config.fillPatternX]
|
||||
@ -16670,6 +16671,19 @@
|
||||
* @param {Number} [config.dragDistance]
|
||||
* @param {Function} [config.dragBoundFunc]
|
||||
* @example
|
||||
* var kerningPairs = {
|
||||
* 'A': {
|
||||
* ' ': -0.05517578125,
|
||||
* 'T': -0.07421875,
|
||||
* 'V': -0.07421875,
|
||||
* },
|
||||
* 'V': {
|
||||
* ',': -0.091796875,
|
||||
* ":": -0.037109375,
|
||||
* ";": -0.037109375,
|
||||
* "A": -0.07421875,
|
||||
* }
|
||||
* }
|
||||
* var textpath = new Konva.TextPath({
|
||||
* x: 100,
|
||||
* y: 50,
|
||||
@ -16677,7 +16691,10 @@
|
||||
* fontSize: '24',
|
||||
* fontFamily: 'Arial',
|
||||
* text: 'All the world\'s a stage, and all the men and women merely players.',
|
||||
* data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50'
|
||||
* data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50',
|
||||
* getKerning: function(leftChar, rightChar) {
|
||||
* return kerningPairs.hasOwnProperty(leftChar) ? pairs[leftChar][rightChar] || 0 : 0
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
Konva.TextPath = function(config) {
|
||||
@ -16696,6 +16713,7 @@
|
||||
var that = this;
|
||||
this.dummyCanvas = Konva.Util.createCanvasElement();
|
||||
this.dataArray = [];
|
||||
this.getKerning = config.getKerning;
|
||||
|
||||
// call super constructor
|
||||
Konva.Shape.call(this, config);
|
||||
@ -17079,11 +17097,20 @@
|
||||
|
||||
var width = Konva.Path.getLineLength(p0.x, p0.y, p1.x, p1.y);
|
||||
|
||||
// Note: Since glyphs are rendered one at a time, any kerning pair data built into the font will not be used.
|
||||
// Can foresee having a rough pair table built in that the developer can override as needed.
|
||||
|
||||
var kern = 0;
|
||||
// placeholder for future implementation
|
||||
if (this.getKerning) {
|
||||
try {
|
||||
// getKerning is a user provided getter. Make sure it never breaks our logic
|
||||
kern = this.getKerning(charArr[i - 1], charArr[i]) * this.fontSize();
|
||||
}
|
||||
catch(e) {
|
||||
kern = 0;
|
||||
}
|
||||
}
|
||||
|
||||
p0.x += kern;
|
||||
p1.x += kern;
|
||||
this.textWidth += kern;
|
||||
|
||||
var midpoint = Konva.Path.getPointOnLine(
|
||||
kern + width / 2.0,
|
||||
@ -18357,7 +18384,7 @@
|
||||
var rotation = Konva.getAngle(node.rotation());
|
||||
|
||||
var dx = rect.x * node.scaleX() - node.offsetX();
|
||||
var dy = rect.y * node.scaleY() - node.offsetX();
|
||||
var dy = rect.y * node.scaleY() - node.offsetY();
|
||||
|
||||
return {
|
||||
x: node.x() + dx * Math.cos(rotation) + dy * Math.sin(-rotation),
|
||||
|
2
konva.min.js
vendored
2
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@ -17,9 +17,23 @@
|
||||
* @param {String} [config.fontVariant] can be normal or small-caps. Default is normal
|
||||
* @param {String} config.text
|
||||
* @param {String} config.data SVG data string
|
||||
* @param {Function} config.getKerning a getter for kerning values for the specified characters
|
||||
* @@shapeParams
|
||||
* @@nodeParams
|
||||
* @example
|
||||
* var kerningPairs = {
|
||||
* 'A': {
|
||||
* ' ': -0.05517578125,
|
||||
* 'T': -0.07421875,
|
||||
* 'V': -0.07421875,
|
||||
* },
|
||||
* 'V': {
|
||||
* ',': -0.091796875,
|
||||
* ":": -0.037109375,
|
||||
* ";": -0.037109375,
|
||||
* "A": -0.07421875,
|
||||
* }
|
||||
* }
|
||||
* var textpath = new Konva.TextPath({
|
||||
* x: 100,
|
||||
* y: 50,
|
||||
@ -27,7 +41,10 @@
|
||||
* fontSize: '24',
|
||||
* fontFamily: 'Arial',
|
||||
* text: 'All the world\'s a stage, and all the men and women merely players.',
|
||||
* data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50'
|
||||
* data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50',
|
||||
* getKerning: function(leftChar, rightChar) {
|
||||
* return kerningPairs.hasOwnProperty(leftChar) ? pairs[leftChar][rightChar] || 0 : 0
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
Konva.TextPath = function(config) {
|
||||
@ -46,6 +63,7 @@
|
||||
var that = this;
|
||||
this.dummyCanvas = Konva.Util.createCanvasElement();
|
||||
this.dataArray = [];
|
||||
this.getKerning = config.getKerning;
|
||||
|
||||
// call super constructor
|
||||
Konva.Shape.call(this, config);
|
||||
@ -429,11 +447,20 @@
|
||||
|
||||
var width = Konva.Path.getLineLength(p0.x, p0.y, p1.x, p1.y);
|
||||
|
||||
// Note: Since glyphs are rendered one at a time, any kerning pair data built into the font will not be used.
|
||||
// Can foresee having a rough pair table built in that the developer can override as needed.
|
||||
|
||||
var kern = 0;
|
||||
// placeholder for future implementation
|
||||
if (this.getKerning) {
|
||||
try {
|
||||
// getKerning is a user provided getter. Make sure it never breaks our logic
|
||||
kern = this.getKerning(charArr[i - 1], charArr[i]) * this.fontSize();
|
||||
}
|
||||
catch(e) {
|
||||
kern = 0;
|
||||
}
|
||||
}
|
||||
|
||||
p0.x += kern;
|
||||
p1.x += kern;
|
||||
this.textWidth += kern;
|
||||
|
||||
var midpoint = Konva.Path.getPointOnLine(
|
||||
kern + width / 2.0,
|
||||
|
@ -83,7 +83,7 @@
|
||||
var rotation = Konva.getAngle(node.rotation());
|
||||
|
||||
var dx = rect.x * node.scaleX() - node.offsetX();
|
||||
var dy = rect.y * node.scaleY() - node.offsetX();
|
||||
var dy = rect.y * node.scaleY() - node.offsetY();
|
||||
|
||||
return {
|
||||
x: node.x() + dx * Math.cos(rotation) + dy * Math.sin(-rotation),
|
||||
|
@ -368,4 +368,85 @@ suite('TextPath', function() {
|
||||
stage.add(layer);
|
||||
showHit(layer);
|
||||
});
|
||||
|
||||
test('Text with kerning', function() {
|
||||
var stage = addStage();
|
||||
|
||||
// simulate lack of kerning support
|
||||
stage.getContainer().style.fontKerning = 'none';
|
||||
|
||||
var layer = new Konva.Layer();
|
||||
var pairs = {
|
||||
'A': {
|
||||
'V': -0.07421875,
|
||||
},
|
||||
'V': {
|
||||
'A': -0.07421875,
|
||||
},
|
||||
}
|
||||
|
||||
const kernedText = new Konva.TextPath({
|
||||
x : 0, y : 30,
|
||||
fill: 'black',
|
||||
text: 'AV',
|
||||
fontSize: 60,
|
||||
data: 'M0,0 L200,0',
|
||||
getKerning: function(leftChar, rightChar) {
|
||||
return pairs.hasOwnProperty(leftChar) ? pairs[leftChar][rightChar] || 0 : 0
|
||||
},
|
||||
});
|
||||
|
||||
const unkernedText = new Konva.TextPath({
|
||||
x : 0, y : 90,
|
||||
fill: 'black',
|
||||
text: 'AV',
|
||||
fontSize: 60,
|
||||
data: 'M0,0 L200,0',
|
||||
});
|
||||
|
||||
layer.add(kernedText);
|
||||
layer.add(unkernedText);
|
||||
stage.add(layer);
|
||||
|
||||
assert(
|
||||
kernedText.getTextWidth() < unkernedText.getTextWidth(),
|
||||
'kerned text lenght must be less then unkerned text length');
|
||||
});
|
||||
|
||||
test('Text with invalid kerning getter should not fail (fallback to unkerned)', function() {
|
||||
var stage = addStage();
|
||||
|
||||
// simulate lack of kerning support
|
||||
stage.getContainer().style.fontKerning = 'none';
|
||||
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
const kernedText = new Konva.TextPath({
|
||||
x : 0, y : 30,
|
||||
fill: 'black',
|
||||
text: 'AV',
|
||||
fontSize: 60,
|
||||
data: 'M0,0 L200,0',
|
||||
getKerning: function(leftChar, rightChar) {
|
||||
// getter that fails
|
||||
throw new Error("something went wrong");
|
||||
},
|
||||
});
|
||||
|
||||
const unkernedText = new Konva.TextPath({
|
||||
x : 0, y : 90,
|
||||
fill: 'black',
|
||||
text: 'AV',
|
||||
fontSize: 60,
|
||||
data: 'M0,0 L200,0',
|
||||
});
|
||||
|
||||
layer.add(kernedText);
|
||||
layer.add(unkernedText);
|
||||
stage.add(layer);
|
||||
|
||||
assert.equal(
|
||||
kernedText.getTextWidth(), unkernedText.getTextWidth(),
|
||||
'should gracefully fallback to unkerned text');
|
||||
})
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user