Photoshop: Scripting: Extract kerning preceding first character

  • 2
  • Problem
  • Updated 4 days ago
  • (Edited)
Hello,

this is a copy of my post from https://forums.adobe.com/thread/2526847, one of the users told me there that it looks like a bug.

I need to extract a value of kerning, that precedes the first character in a text. Here is my script:
var psdFilePath = "C:/adobe/test.psd";  
var psdFile = File(psdFilePath);  
  
var document = open(psdFile);  
var layers = document.layers;  
var result = null;  
  
for (var i = 0; i < layers.length; ++i){  
    var layer = layers[i];  
    if (layer.kind == LayerKind.TEXT){  
        document.activeLayer = layer;  
        result = getKerningInfo().toSource();  
    }  
}  
  
result  
  
function getKerningInfo(){  
    var kerningInfo = new Array;  
    var layerReference = new ActionReference();  
    layerReference.putEnumerated(charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );  
    var layerDescriptor = executeActionGet(layerReference);  
    var textDescriptor = layerDescriptor.getObjectValue(stringIDToTypeID("textKey"));  
    var kerningRanges = textDescriptor.getList(stringIDToTypeID("kerningRange"));  
  
  
    for(var i = 0; i < kerningRanges.count; i++){  
        var kerningRange = kerningRanges.getObjectValue(i);  
        var from = kerningRange.getInteger(stringIDToTypeID("from"));  
        var to = kerningRange.getInteger(stringIDToTypeID("to"));  
        var kerning = kerningRange.getInteger(stringIDToTypeID("kerning"));  
        var kerningItem = {'from': from, 'to': to, 'kerning': kerning};  
        kerningInfo.push(kerningItem);  
    }  
  
    return kerningInfo;  
}

As a result, I get a list containing a single item:
{'from': 0, 'to': 1, 'kerning': -200}  
However, in the file, I have set the value of "kerning between two characters" to:

  • -1000 before the first character
  • -200 before the second character
Here is a screenshot showing it:

Is there something wrong with my code or is it a bug in Photoshop JavaScript API?
Photo of Wojtek Jeczalik

Wojtek Jeczalik

  • 1 Post
  • 0 Reply Likes

Posted 1 year ago

  • 2
Photo of christoph pfaffenbichler

christoph pfaffenbichler, Champion

  • 1356 Posts
  • 214 Reply Likes
It seems the ActionManager kerningRange-handling might be considerably more messed up than what you noticed. 
Apparently it is not possible to maintain the kerning if two or more subsequent kerned intervals follow each other. 

I noticed that when working on a Script to color individual letters, see jpgs (in the first line there is kerning between all letter-pairs, in the second line there is »alternating« kerning). 
When applying the kerningRange only the last value of a chain of bordering values is honoured whereas kerning on a letter-pair that is not kerned with the following and preceding letter works fine. 

That one could set the From- and To-values to cover more than one interval is naturally useless in the context of aesthetically sensitive corrections where the kerning between all the letter pairs may vary. 
Before 

After 


Photo of David Converse

David Converse

  • 747 Posts
  • 220 Reply Likes
That code will only get the last kerning value. Take another look at your for loop.

Maybe change result to an array instead of a flat variable.
Photo of christoph pfaffenbichler

christoph pfaffenbichler, Champion

  • 1356 Posts
  • 214 Reply Likes
What do you mean? 
I applied both the existing List and fed the values into a new List, in both cases the result is wrong. 

And even if I use ScriptingListener-plugin to record a text-edit in which several neighboring intervals get kerned, undo the operation and run the recorded code the result is wrong. 
(Edited)
Photo of David Converse

David Converse

  • 747 Posts
  • 220 Reply Likes
Look at the script posted in the OP. The loop overwrites the variable value which is why it only returns one item.
Photo of christoph pfaffenbichler

christoph pfaffenbichler, Champion

  • 1356 Posts
  • 214 Reply Likes
But I was not referring to that Script, I simply added an observation on how the kerningRange-implementation seems to be buggy even more. 

Like I mentioned earlier one can test this by recording the code (for kerning two neighbouring letter-intervals) that, when being run later on, will produce wrong results. 

And as for issue of the OP: Again recording code does not produce meaningful results as the To/From integers recorded start with 0 and 1 respectively.
So it does not seem possible to Script kerning before the first letter even though it is possible to kern manually. 
(Edited)
Photo of David Converse

David Converse

  • 747 Posts
  • 220 Reply Likes
I was replying to the OP.
Photo of christoph pfaffenbichler

christoph pfaffenbichler, Champion

  • 1356 Posts
  • 214 Reply Likes
Please excuse the confusion. 

But now I’e given the code in the OP a look and I fails to see why the clause
for(var i = 0; i < kerningRanges.count; i++){  
should not be successful in collecting the whole count of items.