Skip to main content
Known Participant
January 1, 2025
Answered

Read fonts from different layers

  • January 1, 2025
  • 3 replies
  • 538 views

 

 

#target photoshop

var originalText = "AAAAAAAAAA"; // Original text
var newText = "bbbbbbbbbb"; // New text

// Get the current document
var currentDocument = app.activeDocument;

// Recursively traverse layer sets, including group layers
function traverseLayerSet(layerSet) {
    for (var i = 0; i < layerSet.layers.length; i++) {
        var layer = layerSet.layers[i];

        // If the layer is a group, recurse into it
        if (layer.typename == "LayerSet") {
            traverseLayerSet(layer); // Recursively traverse layers within this group
        }
        // Check if the layer is a text layer
        else if (layer.kind == LayerKind.TEXT) {
            // Get the text content of the layer
            var textContent = layer.textItem.contents;

            // Check if the text matches the original text
            if (textContent === originalText) { // Find the content
                // Select the layer based on its index
                currentDocument.activeLayer = layer;

                var actionReference = new ActionReference();
                actionReference.putClass(stringIDToTypeID("typeCreateOrEditTool"));
                var actionDescriptor = new ActionDescriptor();
                actionDescriptor.putReference(stringIDToTypeID("null"), actionReference);
                executeAction(stringIDToTypeID("select"), actionDescriptor, DialogModes.NO);

                var actionReference2 = new ActionReference();
                actionReference2.putProperty(stringIDToTypeID("property"), stringIDToTypeID("tool"));
                actionReference2.putEnumerated(stringIDToTypeID("application"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));

                var font = executeActionGet(actionReference2)
                    .getObjectValue(stringIDToTypeID("currentToolOptions"))
                    .getObjectValue(stringIDToTypeID("textToolCharacterOptions"))
                    .getObjectValue(stringIDToTypeID("textStyle"))
                    .getString(stringIDToTypeID("fontPostScriptName"));

                // Get the font
                alert(font);

                layer.textItem.contents = newText; // Replace the text
            }
        }
    }
}

// Start traversing the top-level layers (including layer sets)
traverseLayerSet(currentDocument);

 

 

 As shown in the image, each text layer uses a different font. I want to use the code above to read the fonts from different text layers, but there is an issue. It fails to read the fonts from different layers, and the font retrieved is always the same, even though all my text layers have different fonts. If I use alert(app.activeDocument.activeLayer.textItem.font);, I can successfully retrieve the font, but some fonts trigger an error message:
Error 8500: The requested property does not exist.
Line: 1
->

Correct answer c.pfaffenbichler

1) What difference does knowing the font make? So why not use a try-clause? 

2) Why did you try to get the font from currentToolOptions instead of from the Layer? 

var originalText = "AAAAAA"; // Original text
var newText = "bbbbbbbbbb"; // New text

// Get the current document
var currentDocument = app.activeDocument;

// Recursively traverse layer sets, including group layers
function traverseLayerSet(layerSet) {
    for (var i = 0; i < layerSet.layers.length; i++) {
        var layer = layerSet.layers[i];

        // If the layer is a group, recurse into it
        if (layer.typename == "LayerSet") {
            traverseLayerSet(layer); // Recursively traverse layers within this group
        }
        // Check if the layer is a text layer
        else if (layer.kind == LayerKind.TEXT) {
            // Get the text content of the layer
            var textContent = layer.textItem.contents;

            // Check if the text matches the original text
            if (textContent == originalText) { // Find the content
                try {var font = layer.textItem.font;
                alert(font)} catch (e) {};
                layer.textItem.contents = newText; // Replace the text
            }
        }
    }
}

// Start traversing the top-level layers (including layer sets)
traverseLayerSet(currentDocument);

 

3 replies

c.pfaffenbichler
Community Expert
Community Expert
January 1, 2025

Here is an example of how to collect the font names of all layers in a file (including the names of multiple fonts on individual layers): 

// 2015, use it at your own risk;
#target photoshop
if (app.documents.length > 0) {
var myDocument = app.activeDocument;
//
main ();
};
////////////////////////////////////
function main () {
var theFonts = new Array;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
var applicationDesc = executeActionGet(ref);
var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
//////
for (var m = theNumber; m >= 0; m--) {
try {
var ref = new ActionReference();
ref.putIndex( charIDToTypeID( "Lyr " ), m);
var layerDesc = executeActionGet(ref);
var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
var theName = layerDesc.getString(stringIDToTypeID('name'));
// if not layer group collect values;
if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
var hasText = layerDesc.hasKey(stringIDToTypeID("textKey"));
if (hasText == true) {
var textDesc = layerDesc.getObjectValue(stringIDToTypeID('textKey'));
var paragraphRangeList = textDesc.getList(stringIDToTypeID('paragraphStyleRange'));
var kernRange = textDesc.getList(stringIDToTypeID('kerningRange'));
var rangeList = textDesc.getList(stringIDToTypeID('textStyleRange'));
for (var o = 0; o < rangeList.count; o++) {
var styleDesc = rangeList.getObjectValue(o).getObjectValue(stringIDToTypeID('textStyle'));
// check for default font;
if (styleDesc.hasKey(stringIDToTypeID('fontPostScriptName')) == true) {var aFont = styleDesc.getString(stringIDToTypeID('fontPostScriptName'))}
else {
	var theDefault = styleDesc.getObjectValue(stringIDToTypeID('baseParentStyle'));
	var aFont = theDefault.getString(stringIDToTypeID('fontPostScriptName'));
	};
// add to array;
var theCheck = true;
for (var n = 0; n < theFonts.length; n++) {
if (theFonts[n] == aFont) {theCheck = false}
};
if (theCheck  == true) {theFonts.push(aFont)}
}
}
}
}
catch (e) {};
}
alert ("the result:"+"\n"+theFonts.join("\n"))
};
Known Participant
January 1, 2025

Thank you very much, thank you.

c.pfaffenbichler
Community Expert
c.pfaffenbichlerCommunity ExpertCorrect answer
Community Expert
January 1, 2025

1) What difference does knowing the font make? So why not use a try-clause? 

2) Why did you try to get the font from currentToolOptions instead of from the Layer? 

var originalText = "AAAAAA"; // Original text
var newText = "bbbbbbbbbb"; // New text

// Get the current document
var currentDocument = app.activeDocument;

// Recursively traverse layer sets, including group layers
function traverseLayerSet(layerSet) {
    for (var i = 0; i < layerSet.layers.length; i++) {
        var layer = layerSet.layers[i];

        // If the layer is a group, recurse into it
        if (layer.typename == "LayerSet") {
            traverseLayerSet(layer); // Recursively traverse layers within this group
        }
        // Check if the layer is a text layer
        else if (layer.kind == LayerKind.TEXT) {
            // Get the text content of the layer
            var textContent = layer.textItem.contents;

            // Check if the text matches the original text
            if (textContent == originalText) { // Find the content
                try {var font = layer.textItem.font;
                alert(font)} catch (e) {};
                layer.textItem.contents = newText; // Replace the text
            }
        }
    }
}

// Start traversing the top-level layers (including layer sets)
traverseLayerSet(currentDocument);

 

c.pfaffenbichler
Community Expert
Community Expert
January 1, 2025

Did you create the Script or is this the work of Generative AI? 

Known Participant
January 1, 2025

Generated through AI and completed by combining codes from the forum.