Copy link to clipboard
Copied
Hi,
Please help to get kerning and tracking value for each character using extendscript.
I try this
var textFrame = doc.selection[i];
var textRange = textFrame.textRange;
var textCharactersAll = textRange.characters;
for (var i = 0; i < textCharactersAll.length; i++) {
var character = textCharactersAll[i];
var tracking = character.characterAttributes.tracking;
// Log or do whatever you want with the tracking value
alert("Character " + (i+1) + " tracking: " + tracking);
}
2 Correct answers
the text range and the characters are conflicting. text range doesnt havent characters in this instance. the characters are a part of the text frame and the text range is part of the text frame. both of the below examples gave me correct answers for the tracking
/*using Characters from a textFrame */
var TF = app.activeDocument.selection[0];
var textCharactersAll = TF.characters;
for (var i = 0; i < textCharactersAll.length; i++) {
var character = textCharactersAll[i];
var tracking = character.
...
Hi @Arunkumar25715058ufpl, surprisingly I couldn't find how to do this.
As a workaround, I wrote this script that should achieve what you need. It converts a TextFrame to manual kerning. If you just want the values (without converting) you can just collect the `k` var and return an array of the kerning values.
Let me know if it helps.
- Mark
/**
* Example code to convert auto-kerned text into manual kerning.
* There must be an easier way... right? I just don't know it.
* @author m1b
...
Explore related tutorials & articles
Copy link to clipboard
Copied
the text range and the characters are conflicting. text range doesnt havent characters in this instance. the characters are a part of the text frame and the text range is part of the text frame. both of the below examples gave me correct answers for the tracking
/*using Characters from a textFrame */
var TF = app.activeDocument.selection[0];
var textCharactersAll = TF.characters;
for (var i = 0; i < textCharactersAll.length; i++) {
var character = textCharactersAll[i];
var tracking = character.characterAttributes.tracking;
// Log or do whatever you want with the tracking value
alert("Character " + (i+1) + " tracking: " + tracking);
}
/*using a textRange and the indexes of it */
var TF = app.activeDocument.selection[0];
var TR = TF.textRanges;
for (var i = 0; i < TR.length; i++) {
var character = TR[i];
var tracking = character.characterAttributes.tracking;
// Log or do whatever you want with the tracking value
alert("Character " + (i+1) + " tracking: " + tracking);
}
side note: good idea to not create variables that are the same name as the value you are getting. it can get confusing later on. A lot of example code will just throw "my" in front of whatever to help signify that the variable is something you created. I replaced textFRame and textRange with TF and TR respectively
Copy link to clipboard
Copied
Hi RobOctopus,
Thanks for your reply. Now, I am getting the tracking values as per your suggestion. how to get kerning values?
Copy link to clipboard
Copied
Hi @Arunkumar25715058ufpl, you can use
var km = myCharacter.kerningMethod;
var k = myCharacter.kerning;
You must check kerningMethod first, because if the kerningMethod is an AutoKernType then it will not have a kerning value and may throw an error. if you want to set the kerning, then set the kerningMethod to AutoKernType.NOAUTOKERN.
- Mark
Copy link to clipboard
Copied
Hi Mark,
Kerning Method is AutoKernType.AUTO. But i need to get second character value (200) only.
Copy link to clipboard
Copied
Hi @Arunkumar25715058ufpl, surprisingly I couldn't find how to do this.
As a workaround, I wrote this script that should achieve what you need. It converts a TextFrame to manual kerning. If you just want the values (without converting) you can just collect the `k` var and return an array of the kerning values.
Let me know if it helps.
- Mark
/**
* Example code to convert auto-kerned text into manual kerning.
* There must be an easier way... right? I just don't know it.
* @author m1b
* @discussion https://community.adobe.com/t5/illustrator-discussions/how-to-get-kerning-and-tracking-value-using-extendscript/m-p/14502970
*/
(function () {
var doc = app.activeDocument,
myTextFrame = doc.selection[0] || 0;
if (
!myTextFrame
|| 'TextFrame' !== myTextFrame.constructor.name
)
return alert('Please select a text frame and try again.');
// read the kerning values
var kerningValues = getKerning(myTextFrame);
// apply them to the text frame
applyKerning(myTextFrame, kerningValues);
// alert(kerningValues);
})();
/**
* Returns the textFrame's kerning values as an array.
* @author m1b
* @version 2024-03-22
* @param {TextFrame} textFrame - an Illustrator TextFrame.
* @returns {Array<Number>} - the kerning values.
*/
function getKerning(textFrame) {
// we'll assume zero kerning before first character
var kerning = [];
// work with a duplicate textFrame, unrotated
var dup = textFrame.duplicate(),
len = dup.characters.length - 1,
r = getRotationFromMatrix(dup.matrix);
if (0 !== r)
// unrotate it (otherwise `width` is meaningless)
dup.rotate(-r);
// the master width
var width = dup.width;
// get the manual values
for (var i = 0; i <= len; i++) {
try {
kerning[i] = dup.characters[i].kerning;
} catch (error) { }
};
// now determine auto kerning values using duplicates
for (var i = 0, ch, tf; i < len; i++) {
if (undefined != kerning[i + 1])
continue;
tf = dup.duplicate();
ch = tf.characters[i];
// remove auto kerning (kerning will be zero)
ch.kerningMethod = AutoKernType.NOAUTOKERN;
// calculate auto kerning amount by change in width
kerning[i + 1] = Math.round((width - tf.width) * 1000 / ch.size)
tf.remove();
}
dup.remove();
return kerning;
};
/**
* Apply an array of kerning values to a textFrame.
* @author m1b
* @version 2024-03-22
* @param {TextFrame} textFrame - an Illustrator TextFrame.
* @param {Array<Number>} kerning - array of kerning values.
*/
function applyKerning(textFrame, kerning) {
// remove auto kerning
textFrame.textRange.kerningMethod = AutoKernType.NOAUTOKERN;
var len = Math.min(textFrame.characters.length, kerning.length);
for (var i = len - 1; i >= 0; i--)
if (undefined != kerning[i])
textFrame.characters[i].kerning = kerning[i];
};
/**
* Returns the rotation amount, in degrees,
* of the given (not skewed) matrix.
* @param {Matrix} matrix - an Illustrator Matrix.
* @returns {Number}
*/
function getRotationFromMatrix(matrix) {
if (matrix.constructor.name !== 'Matrix')
throw Error("getRotationFromMatrix: bad `matrix` supplied.");
// calculate the horizontal and vertical scaling factors
var sX = Math.sqrt(matrix.mValueA * matrix.mValueA + matrix.mValueC * matrix.mValueC),
radians = Math.acos(matrix.mValueA / sX),
degrees = radians * (180 / Math.PI);
return Math.round(degrees * 1000) / 1000;
};
Edit 2024-03-22: updated code due to bugs found by @Arunkumar25715058ufpl. Split into `getKerning` and `applyKerning` functions. Now handles mix of manual and auto kerning values.
Copy link to clipboard
Copied
Hi Mark,
I run your code it returns the k value as 0 or -10 only. I attached my ai file. Also, I set kerning manually in Illustrator for the second character. I try to get that value using extendscript.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Thanks @Arunkumar25715058ufpl, sorry about the bug! I have updated code now.
- Mark
Copy link to clipboard
Copied
Hi Mark,
Thanks for your support. Now I get the kerning values.

