Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any way to get the glyph name? #47

Open
opcodewriter opened this issue Oct 2, 2023 · 9 comments
Open

Any way to get the glyph name? #47

opcodewriter opened this issue Oct 2, 2023 · 9 comments

Comments

@opcodewriter
Copy link

opcodewriter commented Oct 2, 2023

Can I use your library to get the glyph's name (if it exists)?
Some fonts have it set I think.
Thanks!

@photopea
Copy link
Owner

photopea commented Oct 2, 2023

what is a glyphs name?

@opcodewriter
Copy link
Author

opcodewriter commented Oct 3, 2023

@photopea
Other JS libraries (opentype and fontkit) are able to parse and return the glyph names.

See fontkit's glyph object for example: https://github.com/foliojs/fontkit#glyph-objects

name - the glyph name in the font

Please also see https://stackoverflow.com/questions/23185221/getting-the-glyph-name-from-a-ttf-or-otf-font-file

@photopea
Copy link
Owner

photopea commented Oct 3, 2023

I am familiar with the OpenType specification, but I have never heard of glyph names. Could you show us some examples, what glyph should have what names? Also, why would you need a name of a glyph?

@opcodewriter
Copy link
Author

opcodewriter commented Oct 4, 2023

Sure, it's easy to parse the glyphs with a capable library, here's an example with fontkit:

const fontkit = require('fontkit');

const font = fontkit.openSync('Font Awesome 5 Free-Solid-900.otf');

for (let iGlyph = 0; iGlyph < font.numGlyphs; ++iGlyph) {
    const glyph = font.getGlyph(iGlyph);
    if (!glyph) {
        continue;
    }

    console.log(glyph.name);
}

Output:

image

Also, why would you need a name of a glyph?

Glyph names are used in icon fonts to allow developers use the icons easier. Instead of hexadecimal, developers specify the glyph name: https://fontawesome.com/docs/desktop/add-icons/glyphs

I'm trying to parse fonts for glyph names for a little tool I'm working on for myself.

I'd like to use Typr.js instead of other fonts, your library seems slimmer.

Would you add support for glyph names?

@photopea
Copy link
Owner

photopea commented Oct 4, 2023

Ok, I see that there are glyph names in the CFF table. So this is possible only for some OTF files, impossible for TTF files.

But each glyph in the FontAwesome has an unicode code, e.g. this https://fontawesome.com/icons/magnifying-glass?f=classic&s=solid has an unicode code 0xf002 , so you can use Typr.U.codeToGlyph(font, 0xf002)

@opcodewriter
Copy link
Author

opcodewriter commented Oct 5, 2023

@photopea Thanks for your reply, but I'm not following you.

How does your example Typr.U.codeToGlyph(font, 0xf002) helps in getting the glyph name?

Typr.U.codeToGlyph seems to be returning an index.
How can I use the index to get the glyph name?

@photopea
Copy link
Owner

photopea commented Oct 5, 2023

I am suggesting to use only unicode codes, do not use the glyph names at all. Refer to glyphs by their unicode codes.

@opcodewriter
Copy link
Author

Oh, but I need the glyph names, that's the whole point :) I need to be able to automatically get the icon (glyph) names out of an icon font.

@herrstrietzel
Copy link

Glyph names – if available – names are stored in the post table.
The mapping works via numGlyphs - numeric glyph ID indices and
names item/property.

Currently, they are not included in Typr.js but you can extend the table parsing like so:

/**
 * Fork: new post items
 */
Typr["T"].post = {
	parseTab: function (data, offset, length) {
		var bin = Typr["B"];
		var obj = {};

		obj["version"] = bin.readFixed(data, offset); offset += 4;
		obj["italicAngle"] = bin.readFixed(data, offset); offset += 4;
		obj["underlinePosition"] = bin.readShort(data, offset); offset += 2;
		obj["underlineThickness"] = bin.readShort(data, offset); offset += 2;


		/**
		 * Add post table items
		 * like name records - 
		 * provides glyph id to name mapping
		 */
		obj["isFixedPitch"] = bin.readUint(data, offset); offset += 4;
		obj["minMemType42"] = bin.readUint(data, offset); offset += 4;
		obj["maxMemType42"] = bin.readUint(data, offset); offset += 4;
		obj["minMemType1"] = bin.readUint(data, offset); offset += 4;
		obj["maxMemType1"] = bin.readUint(data, offset); offset += 4;


		// standard name records
		var standardNames = '.notdef .null nonmarkingreturn space exclam quotedbl numbersign dollar percent ampersand quotesingle parenleft parenright asterisk plus comma hyphen period slash zero one two three four five six seven eight nine colon semicolon less equal greater question at A B C D E F G H I J K L M N O P Q R S T U V W X Y Z bracketleft backslash bracketright asciicircum underscore grave a b c d e f g h i j k l m n o p q r s t u v w x y z braceleft bar braceright asciitilde Adieresis Aring Ccedilla Eacute Ntilde Odieresis Udieresis aacute agrave acircumflex adieresis atilde aring ccedilla eacute egrave ecircumflex edieresis iacute igrave icircumflex idieresis ntilde oacute ograve ocircumflex odieresis otilde uacute ugrave ucircumflex udieresis dagger degree cent sterling section bullet paragraph germandbls registered copyright trademark acute dieresis notequal AE Oslash infinity plusminus lessequal greaterequal yen mu partialdiff summation product pi integral ordfeminine ordmasculine Omega ae oslash questiondown exclamdown logicalnot radical florin approxequal Delta guillemotleft guillemotright ellipsis nonbreakingspace Agrave Atilde Otilde OE oe endash emdash quotedblleft quotedblright quoteleft quoteright divide lozenge ydieresis Ydieresis fraction currency guilsinglleft guilsinglright fi fl daggerdbl periodcentered quotesinglbase quotedblbase perthousand Acircumflex Ecircumflex Aacute Edieresis Egrave Iacute Icircumflex Idieresis Igrave Oacute Ocircumflex apple Ograve Uacute Ucircumflex Ugrave dotlessi circumflex tilde macron breve dotaccent ring cedilla hungarumlaut ogonek caron Lslash lslash Scaron scaron Zcaron zcaron brokenbar Eth eth Yacute yacute Thorn thorn minus multiply onesuperior twosuperior threesuperior onehalf onequarter threequarters franc Gbreve gbreve Idotaccent Scedilla scedilla Cacute cacute Ccaron ccaron dcroat'.split(' ');


		if (obj["version"] === 2.0) {
			obj["numGlyphs"] = bin.readUshort(data, offset); offset += 2;
			obj["glyphNameIndex"] = [];
			for (var i = 0; i < obj["numGlyphs"]; i++) {
				obj["glyphNameIndex"].push(bin.readUshort(data, offset)); offset += 2;
			}

			// Calculate the maximum byte length for names
			var namesOffset = offset;
			var namesLength = length - (namesOffset - offset); // Remaining bytes in the `post` table
			var namesStr = bin.readASCII(data, offset, namesLength);

			// split name string
			var namesArr = namesStr.split(/\n| /g).map(val => { return val.split(/[^\x20-\x7E]+/) }).flat().filter(Boolean);


			// merge with standard names
			obj["names"] = obj["glyphNameIndex"].map(index => {
				if (index < standardNames.length) {
					// Use standard names for indices < 258
					return standardNames[index];
				} else {
					// Adjust for custom names
					var customIndex = index - standardNames.length;
					// Use fallback if custom name is missing
					return namesArr[customIndex] || `.glyph${index}`;
				}
			});
		}
		return obj;
	}
};

I've included this addition to my experimental fork. See https://github.com/herrstrietzel/Typr.js/blob/gh-pages/src/Typr.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants