List fonts used in PSD files

Upload Photoshop Scripts, download Photoshop Scripts, Discussion and Support of Photoshop Scripts

Moderators: Tom, Kukurykus

Mike Hale

List fonts used in PSD files

Post by Mike Hale »

This is for dorian at Adobe's forum
edit: Here is an updated version. MH

Code: Select allfunction main(){
Stdlib = function Stdlib() {};
Stdlib.findFiles = function(folder, mask) {//from Xbytor's Xtools
     var files = Stdlib.getFiles(folder, mask);
     var folders = Stdlib.getFolders(folder);

     for (var i = 0; i < folders.length; i++) {
       var f = folders;
       var ffs = Stdlib.findFiles(f, mask);
       while (ffs.length > 0) {
         files.push(ffs.shift());
       }
     }
     return files;
   };

   Folder.prototype.findFiles = function(mask) {
     return Stdlib.findFiles(this, mask);
   };
   Stdlib.getFiles = function(folder, mask) {
  var files = [];
  var getF;
  if (Folder.prototype._getFiles) {
    getF = function(f, m) { return f._getFiles(m); }
  } else {
    getF = function(f, m) { return f.getFiles(m); }
  }

  if (mask instanceof RegExp) {
    var allFiles = getF(folder);
    for (var i = 0; i < allFiles.length; i = i + 1) {
      var f = allFiles;
      if (decodeURI(f.absoluteURI).match(mask)) {
        files.push(f);
      }
    }
  } else if (typeof mask == "function") {
    var allFiles = getF(folder);
    for (var i = 0; i < allFiles.length; i = i + 1) {
      var f = allFiles;
      if (mask(f)) {
        files.push(f);
      }
    }
  } else {
    files = getF(folder, mask);
  }

  return files;
};
Stdlib.getFolders = function(folder) {
  return Stdlib.getFiles(folder, function(file) {
                           return file instanceof Folder; });
}
   
function getDocFonts(){
function traverseLayers (doc, ftn, reverse) { //from Xbytor

  function _traverse(doc, layers, ftn, reverse) {
    var ok = true;
    for (var i = 1; i <= layers.length && ok != false; i++) {
      var index = (reverse == true) ? layers.length-i : i - 1;
      var layer = layers[index];

      if (layer.typename == "LayerSet") {
        ok = _traverse(doc, layer.layers, ftn, reverse);
      } else {
        ok = ftn(doc, layer);
      }
    }
    return ok;
  };

  return _traverse(doc, doc.layers, ftn, reverse);
};
function getLayersList(doc, reverse) {
  function _ftn(doc, layer) {

   if(layer.kind == LayerKind.TEXT){ _ftn.list.push(layer);};
  };

  _ftn.list = [];
  traverseLayers(doc, _ftn, reverse);

  return _ftn.list;
};
Array.prototype.add = function(obj) { //from Andrew Hall
   if (this.toString().search(RegExp("(?:^|,)" + obj.toString() + "(?:$|,)")) == -1) this.push(obj);
};
function getFontInfo(){
   var info = new Array;
   var ref = new ActionReference();
      ref.putEnumerated( stringIDToTypeID( "layer" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
   var desc= executeActionGet( ref )
   var list =  desc.getObjectValue(charIDToTypeID("Txt ")) ;
   var tsr =  list.getList(charIDToTypeID("Txtt")) ;
   for(var i = 0;i<tsr.count;i++){
      var tsr0 =  tsr.getObjectValue(i) ; 
      var textStyle = tsr0.getObjectValue(charIDToTypeID("TxtS"));
      var font = textStyle.getString(charIDToTypeID("FntN" ));
      var style = textStyle.getString(charIDToTypeID( "FntS" ));
      font = font+"-"+style;
        info.add(font);
         }
   return info;
};

   
var doc = app.activeDocument;
var allLayers = getLayersList(doc);
if (allLayers.length>0){
   var allFonts = new Array;
   for(var i = 0;i<allLayers.length;i++){
       if(allLayers.kind == LayerKind.TEXT){
        app.activeDocument.activeLayer = allLayers;
        allFonts.add(getFontInfo());
      }
     };
   }
return allFonts;
};


var listOfFonts =  new Array;
var selectedFolder = Folder.selectDialog( "Please select the input folder", Folder( "~" ) );
if(selectedFolder == null) return;
var psdFiles = selectedFolder.findFiles(/\.psd$|\.PSD$/);
   for(var i = 0;i < psdFiles.length; i++){
      var doc = open(psdFiles);
      var test = getDocFonts();
      if(test != undefined){
         listOfFonts.push([psdFiles.name,test])
      };
      doc.close(SaveOptions.DONOTSAVECHANGES);
   };
   
var f = new File(selectedFolder+"/fonts.txt") ;
if (!f.open("w")) {
    throw "Unable to open file: " + f.error;
};
f.writeln("File,Fonts");
var fullList = new Array;
for(var i = 0;i<listOfFonts.length;i++){
   f.writeln(listOfFonts);
   if(listOfFonts[1].length == 1){
      fullList.add(listOfFonts[1]);
   }else{
      for(var idx = 0; idx<listOfFonts[i][1].length;idx++){
         fullList.add(listOfFonts[i][1][idx].shift());
      };
   };   
};
f.writeln();
f.writeln("List of fonts used in all documents")
fullList.sort();
for(var i = 0;i<fullList.length;i++){
   f.writeln(fullList[i]);
   };
f.close();
};
main();
navjotjsingh

List fonts used in PSD files

Post by navjotjsingh »

This does not seem to work in CS3. After selecting the folder, it hangs in PS CS3.
Mike Hale

List fonts used in PSD files

Post by Mike Hale »

It runs for me in CS3.

Did you get any error messages?

Did the folder you selected have any psd files?

Mike
navjotjsingh

List fonts used in PSD files

Post by navjotjsingh »

Yes the folder contains the PSD file, but after selecting the folder, PS hangs.

Error Popup shows

Error 21: undefined is not an object.
Line: 87
- > Array.prototype.add = function(obj) {//from Andrew Hall
Mike Hale

List fonts used in PSD files

Post by Mike Hale »

I don't understand why you are getting that error or why it works for me in CS3 without error messages.

I did make some changes to the script today but they are not CS3 related. They fix logic errors that came up while testing this for CS3.

One was to change the file mask so it now finds both upper and lower case file ext.
It now skips non-text layers so it runs faster.
And it now closes all images it opens. It was leaving images without text layers open.
navjotjsingh

List fonts used in PSD files

Post by navjotjsingh »

Your code does generate a fonts.txt file, but still error does comes up.

BTW can fonts.txt consist of two consecutive commas without a font name in between? Is the following output normal? Since I have all the fonts given in fonts.txt installed, but even then PS says fonts missing for the PSD file.

Output of fonts.txt:

File,Fonts
biddir.psd,Franklin Gothic Medium-Regular,Franklin Gothic Demi -Regular ,,KyrillaSansSerif-Black-Regular,Lucida Sans Unicode-Regular,FranklinGothic-Book
navjotjsingh

List fonts used in PSD files

Post by navjotjsingh »

Ok..got it...It is giving error with a particular psd file only, I tried on another psd file, and It ran good.
mattjay84

List fonts used in PSD files

Post by mattjay84 »

This is a brilliant script and could potentially save me loads of time and effort (I have over 8000 psd's that I need to get the fonts from!)

I've managed to establish though that if any of the test layers are blank it throws out the Error 21: undefined is not an object.
Line: 87
- > Array.prototype.add = function(obj) {//from Andrew Hall.

Could someone who knows what they're doing with javascript write me a version that ignores blank text layers?

Your help would be much appreciated.

Thanks Matt
Mike Hale

List fonts used in PSD files

Post by Mike Hale »

Strange it works for me even if the text layer is blank. But if it is blank then it doesn't really have a font. See if this works for you.

Code: Select allfunction main(){
Stdlib = function Stdlib() {};
Stdlib.findFiles = function(folder, mask) {//from Xbytor's Xtools
     var files = Stdlib.getFiles(folder, mask);
     var folders = Stdlib.getFolders(folder);

     for (var i = 0; i < folders.length; i++) {
       var f = folders;
       var ffs = Stdlib.findFiles(f, mask);
       while (ffs.length > 0) {
         files.push(ffs.shift());
       }
     }
     return files;
   };

   Folder.prototype.findFiles = function(mask) {
     return Stdlib.findFiles(this, mask);
   };
   Stdlib.getFiles = function(folder, mask) {
  var files = [];
  var getF;
  if (Folder.prototype._getFiles) {
    getF = function(f, m) { return f._getFiles(m); }
  } else {
    getF = function(f, m) { return f.getFiles(m); }
  }

  if (mask instanceof RegExp) {
    var allFiles = getF(folder);
    for (var i = 0; i < allFiles.length; i = i + 1) {
      var f = allFiles;
      if (decodeURI(f.absoluteURI).match(mask)) {
        files.push(f);
      }
    }
  } else if (typeof mask == "function") {
    var allFiles = getF(folder);
    for (var i = 0; i < allFiles.length; i = i + 1) {
      var f = allFiles;
      if (mask(f)) {
        files.push(f);
      }
    }
  } else {
    files = getF(folder, mask);
  }

  return files;
};
Stdlib.getFolders = function(folder) {
  return Stdlib.getFiles(folder, function(file) {
                           return file instanceof Folder; });
}
   
function getDocFonts(){
function traverseLayers (doc, ftn, reverse) { //from Xbytor

  function _traverse(doc, layers, ftn, reverse) {
    var ok = true;
    for (var i = 1; i <= layers.length && ok != false; i++) {
      var index = (reverse == true) ? layers.length-i : i - 1;
      var layer = layers[index];

      if (layer.typename == "LayerSet") {
        ok = _traverse(doc, layer.layers, ftn, reverse);
      } else {
        ok = ftn(doc, layer);
      }
    }
    return ok;
  };

  return _traverse(doc, doc.layers, ftn, reverse);
};
function getLayersList(doc, reverse) {
  function _ftn(doc, layer) {

   if(layer.kind == LayerKind.TEXT){ _ftn.list.push(layer);};
  };

  _ftn.list = [];
  traverseLayers(doc, _ftn, reverse);

  return _ftn.list;
};
Array.prototype.add = function(obj) { //from Andrew Hall
   if (this.toString().search(RegExp("(?:^|,)" + obj.toString() + "(?:$|,)")) == -1) this.push(obj);
};
function getFontInfo(){
   var info = new Array;
   var ref = new ActionReference();
      ref.putEnumerated( stringIDToTypeID( "layer" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
   var desc= executeActionGet( ref )
   var list =  desc.getObjectValue(charIDToTypeID("Txt ")) ;
   var tsr =  list.getList(charIDToTypeID("Txtt")) ;
   for(var i = 0;i<tsr.count;i++){
      var tsr0 =  tsr.getObjectValue(i) ;
      var textStyle = tsr0.getObjectValue(charIDToTypeID("TxtS"));
      var font = textStyle.getString(charIDToTypeID("FntN" ));
      var style = textStyle.getString(charIDToTypeID( "FntS" ));
      font = font+"-"+style;
        info.add(font);
         }
   return info;
};

   
var doc = app.activeDocument;
var allLayers = getLayersList(doc);
if (allLayers.length>0){
   var allFonts = new Array;
   for(var i = 0;i<allLayers.length;i++){
       if(allLayers.kind == LayerKind.TEXT){
        app.activeDocument.activeLayer = allLayers;
      var fontInfo = getFontInfo();
        if(fontInfo.length > 0) allFonts.add(getFontInfo());
      }
     };
   }
return allFonts;
};


var listOfFonts =  new Array;
var selectedFolder = Folder.selectDialog( "Please select the input folder", Folder( "~" ) );
if(selectedFolder == null) return;
var psdFiles = selectedFolder.findFiles(/\.psd$|\.PSD$/);
   for(var i = 0;i < psdFiles.length; i++){
      var doc = open(psdFiles);
      var test = getDocFonts();
      if(test != undefined){
         listOfFonts.push([psdFiles.name,test])
      };
      doc.close(SaveOptions.DONOTSAVECHANGES);
   };
   
var f = new File(selectedFolder+"/fonts.txt") ;
if (!f.open("w")) {
    throw "Unable to open file: " + f.error;
};
f.writeln("File,Fonts");
var fullList = new Array;
for(var i = 0;i<listOfFonts.length;i++){
   f.writeln(listOfFonts);
   if(listOfFonts[1].length == 1){
      fullList.add(listOfFonts[1]);
   }else{
      for(var idx = 0; idx<listOfFonts[i][1].length;idx++){
         fullList.add(listOfFonts[i][1][idx].shift());
      };
   };   
};
f.writeln();
f.writeln("List of fonts used in all documents")
fullList.sort();
for(var i = 0;i<fullList.length;i++){
   f.writeln(fullList[i]);
   };
f.close();
};
main();
mattjay84

List fonts used in PSD files

Post by mattjay84 »

That works, you've made my weekend!

btw. these blank text layers have had text in them to specify to font info, then it's deleted (they're online editable greeting cards)

Thanks a million.
Matt