Skip to main content
zuhair777
Inspiring
September 15, 2024
Question

To list all the glyphs and their counts used in a document from a specific font

  • September 15, 2024
  • 5 replies
  • 7761 views

I am trying to make a script to list all the glyphs by their names or IDs and their counts in a document. The glyphs should be listed by their names or IDs (not by Unicode) as each Unicode character has several alternate shapes and I want to get result for each and every alternate shape. I have tried but in vain. Here is my script that I am working on.

 

// Get the active document
var doc = app.activeDocument;

// Define an object to store the glyph name counts
var glyphCounts = {};

// Define the output file path
var outputFile = File("~/Desktop/GlyphCount.txt");
outputFile.open("w");

// Write the initial line to the file
outputFile.writeln("Glyph Counts for the font: Arabic Font 1");

// Function to process characters and count glyphs
function countGlyphs(character) {
    try {
        // Check if the character has glyphs
        if (character.hasOwnProperty('glyphs') && character.glyphs.length > 0) {
            var glyph = character.glyphs[0]; // Get the first glyph object
            var glyphName = glyph.glyphName; // Get the glyph name
            
            // Use a placeholder if glyphName is undefined
            if (!glyphName) {
                glyphName = "UnknownGlyph";
            }

            // Update the glyph count based on the glyph name
            if (glyphCounts[glyphName] === undefined) {
                glyphCounts[glyphName] = 1;
            } else {
                glyphCounts[glyphName]++;
            }

            // Debug output using alerts
            alert("Glyph: " + glyphName + ", Count: " + glyphCounts[glyphName]);
        } else {
            alert("No glyphs found for character.");
        }
    } catch (e) {
        // Log errors if glyph retrieval fails
        alert("Error processing character. Error: " + e.toString());
    }
}

// Loop through all stories (text frames) in the document
for (var i = 0; i < doc.stories.length; i++) {
    var story = doc.stories[i];

    // Loop through all characters in the story
    for (var j = 0; j < story.characters.length; j++) {
        var character = story.characters[j];
        var font = character.appliedFont.name;

        // Check if the character is from the specific font you're interested in
        if (font === "Arabic Font 1") {
            countGlyphs(character);
        }
    }
}

// Write the glyph counts to the file
for (var glyphName in glyphCounts) {
    outputFile.writeln("Glyph: " + glyphName + ", Count: " + glyphCounts[glyphName]);
}

// Close the file
outputFile.close();

// Notify the user
alert("Glyph count saved to " + outputFile.fsName);


Any help is greatly appreciated.

This topic has been closed for replies.

5 replies

zuhair777
zuhair777Author
Inspiring
September 16, 2024
Robert at ID-Tasker
Legend
September 16, 2024

@zuhair777

 

Why your link is no linger valid?

 

zuhair777
zuhair777Author
Inspiring
September 17, 2024

 

Dirk Becker, from your post it appears that you are on Mac but I am on Windows. Does your Plugin work on Windows? If you could add another function to it, to find the occurences of these glyphs in the document e.g. uni064C has 7 occurences in the document, we should be able to search for these occurences in the document then it would be of great help.

Marc Autret
Legend
September 16, 2024
Legend
September 19, 2024

Interesting - DeliverGlyphs also uses find/change glyph, as I suggested earlier on, same as the old idea of Dave Saunders that Joel found.

 

This may not work though with fonts that substitute a single character with multiple glyphs - such as ligature decomposition as mentioned in the OpenType specification. I don't have a concrete example at hand to try.

https://learn.microsoft.com/en-us/typography/opentype/otspec181/gsub

Same with contextual substitution, where entire glyph sequences are exchanged for others. You must inspect the output of the font program defining those substitutions to know the final output, and even then there won't be an exact single character to change.

Legend
September 16, 2024

The composer produces a sequence of character codes and associated opentype features.

Those opentype features can get specified by dedicated attributes - e.g. stylistic set, nominator/denominator, slashed zero and umpteen others, or they can get specified out of context: positional form e.g. first/middle/last character of a word. There is also an attribute to directly invoke any opentype feature.

I think that the "form" in question is here referring to the positional form.

https://learn.microsoft.com/en-us/typography/opentype/spec/features_fj#init

https://learn.microsoft.com/en-us/typography/opentype/spec/features_fj#tag-fina

The term "form" is also used for other meanings, e.g. "capital form".

Joel might be thinking of leading hangul forms?

https://learn.microsoft.com/en-us/typography/opentype/spec/features_ko#tag-ljmo

 

The composer then passes those characters and OT features to the font program. This translates them into a sequence of glyph IDs, plus transformations (as in positioning and scaling matrix).

There is no direct mapping - a character can produce multiple glyphs, or multiple characters may result in a single glyph e.g. "st" ligatures, fractions "1/2". Superscript may produce a different glyph or may get fauxed by scaling.

 

The output of the composer is stored in a family of data structures called wax. These are not accessible to scripting, you'd need a C++ plug-in to report on them. This wax is what keeps e.g. old CS2 documents in their original state until you start editing causing a partial or full recompose.

 

Sharing examples in DM rather than posting to the forum limits their use. E.g. good to him when Robert can have a look at a transient share but that keeps out others that may come along far in the future. I'll take an example from a different thread instead - the recent one about Kashidas.

 

The screenshot below is from a plug-in, it shows the different glyphs used for the positional form opentype features, for the first word. It still uses left-to-right, haven't yet added r2l for arabic, for lack of examples when I wrote the plug-in. Labels are localized to German, should be still understandable.

 

 

zuhair777
zuhair777Author
Inspiring
September 16, 2024

In Arabic, most of the letters have four shapes or four forms (1) isolated, (2) initial, (3) medial and (4) final as shown in the image. Arabic script is written from right to left.

The letter Baa (with a dot below) ب has a Unicode value but its other forms don’t have any Unicode values. These shapes automatically change with the the preceding and succeeding combining letters. In more complex Arabic fonts even a single letter may have a large number of initial shapes for a single Unicode character depending on the succeeding joining letters after it as shown in the image below. These are all alternate initial shapes for a single character Baa (with a dot below).

Below are different alternate medial shapes for the same letter Baa (with a dot below).

By "glyph id" I mean the numerical index of these particular glyphs in a particular font. So I am trying to create a script to list all the glyphs, by their IDs, and their counts in a perticular document .

Robert at ID-Tasker
Legend
September 16, 2024

How about export to IDML - or even snippet? 

 

There should be info which glyph / form should be used / displayed - unless, it's done when text is rendered?

 

Robert at ID-Tasker
Legend
September 15, 2024

@zuhair777

 

Character doesn't have glyphs collection - only glyphForm and: 

 

https://www.indesignjs.de/extendscriptAPI/indesign-latest/#AlternateGlyphForms.html#d1e85227

 

 

Robert at ID-Tasker
Legend
September 15, 2024

@zuhair777 

 

Same text - with Swash Alternates ON on the left and OFF on the right:

 

 

returns the same value for the Glyph Form:

 

 

And as per link provided earlier:

 

AlternateGlyphForms.NONE

Does not use an alternate form.

1852796517

 

Could you please provide a sample INDD / IDML file for testing?

 

zuhair777
zuhair777Author
Inspiring
September 15, 2024

I appreciate your information. If we create a PDF from InDesign, can we get the list from it.

Lukas Engqvist
Community Expert
Community Expert
September 15, 2024

I'm not good enough at scripting to be able to help you, but would test the face book scripting group https://www.facebook.com/groups/indesignscripting/