Sunday, April 09, 2006
How to check for missing fonts
I've been commissioned to write a script that helps with the back-end of a workflow, exporting/printing completed documents. Or, to be a little pedantic about it, allegedly completed documents. But what if a document has missing fonts or links? Or if links need updating?
Of these three possibilities, only the third can be dealt with automatically. And finding that links are missing is easy (just check the status property of each link). That will allow the script to check for either links that need relinking or updating, taking appropriate action for each. But what about missing fonts?
Well, the first thing I realized was that if fonts are missing, all I need to do is report that to the user and advise them to use the menu item Find Font... on the Type menu to fix it. So, I need a quick way to find out if any font needed by the document is missing. I ran a timing loop against each of the properties of a font, like this:
718 allowEditableEmbedding
922 allowOutlines
856 allowPDFEmbedding
894 allowPrinting
357 fontFamily (doesn't give error)
754 fontType
915 index (doesn't give error)
857 location
460 name (doesn't give error)
371 parent (doesn't give error)
930 postscriptName
4885 properties (doesn't give error)
911 restrictedPrinting
911 status (doesn't give error)
But if all I want to know is whether or not any fonts are missing, I can simply do this:
Of these three possibilities, only the third can be dealt with automatically. And finding that links are missing is easy (just check the status property of each link). That will allow the script to check for either links that need relinking or updating, taking appropriate action for each. But what about missing fonts?
Well, the first thing I realized was that if fonts are missing, all I need to do is report that to the user and advise them to use the menu item Find Font... on the Type menu to fix it. So, I need a quick way to find out if any font needed by the document is missing. I ran a timing loop against each of the properties of a font, like this:
//DESCRIPTION: Checking for missing document fontsThis was the last test I ran, so it shows the alphabetically last propery, status. The results are shown below (the numbers show how many milliseconds it took to attempt to get the properties of a document that had two missing fonts). Notice that some of the properties are available even for missing fonts. If I wanted to warn the user about specific missing fonts, I'd have to use the status property, and then cycle through the results.
var myStartTime = new Date();
aDoc = app.activeDocument;
for (var j = 0; 100 > j; j++) {
try {
aFonts = aDoc.fonts.everyItem().status;
} catch (e) {
beep();
}
}
var myEndTime = new Date();
var myDuration = (myEndTime - myStartTime);
prompt("", "status " + myDuration)
718 allowEditableEmbedding
922 allowOutlines
856 allowPDFEmbedding
894 allowPrinting
357 fontFamily (doesn't give error)
754 fontType
915 index (doesn't give error)
857 location
460 name (doesn't give error)
371 parent (doesn't give error)
930 postscriptName
4885 properties (doesn't give error)
911 restrictedPrinting
911 status (doesn't give error)
But if all I want to know is whether or not any fonts are missing, I can simply do this:
try {Why do I choose the location property? Because that's the first one I thought of user and the timing test says that the results are just about all the same (the minor differences could easily be the result of blips while I was running the script; indeed, I'm showing the lowest result of three or four runs for most of the properties).
fontLocs = app.activeDocument.fonts.everyItem().location;
} catch (e) {
errorExit("Active document has missing fonts; please correct using Type/Find Font and try again.");
}