/*
 *	clipttf.c
 *
 *	TrueType font
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2016 Naoyuki Sawa
 *
 *	* Sun Nov 27 23:52:51 JST 2016 Naoyuki Sawa
 *	- 1st 儕儕乕僗丅
 *	- 摉儌僕儏乕儖偵偼丄娐嫬埶懚偟側偄張棟偲偟偰丄TrueType_GetFontNameList()偩偗傪娷傔傑偟偨丅
 *	  Windows娐嫬偵埶懚偡傞張棟偼丄DxlibHelper.cpp偵TrueType_AddFontFile(),TrueType_AddMemoryFont()傪捛壛偟傑偟偨丅
 */
#include "clip.h"
/****************************************************************************
 *	
 ****************************************************************************/
//仩嶲峫帒椏:乽Microsoft Typography - The OpenType Font File乿(https://www.microsoft.com/typography/otspec/otff.htm)
struct TTCHeader {
	uint32_t		TTCTag;				//TrueType Collection ID string: 'ttcf'
	uint32_t		Version;			//Version of the TTC Header (1.0), 0x00010000 or (2.0), 0x00020000
	uint32_t		numFonts;			//Number of fonts in TTC
//	uint32_t		OffsetTable[numFonts];		//Array of offsets to the OffsetTable for each font from the beginning of the file
//	uint32_t		ulDsigTag;			//Tag indicating that a DSIG table exists, 0x44534947 ('DSIG') (null if no signature)			劉
//	uint32_t		ulDsigLength;			//The length (in bytes) of the DSIG table (null if no signature)					劌偙傟傜偺僼傿乕儖僪偼(Version=2.0)偺応崌偩偗懚嵼偟傑偡丅
//	uint32_t		ulDsigOffset;			//The offset (in bytes) of the DSIG table from the beginning of the TTC file (null if no signature)	劊
};
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct OffsetTable {
	uint32_t		sfntVersion;			//0x00010000 or 'OTTO' - see below.
	uint16_t		numTables;			//Number of tables.
	uint16_t		searchRange;			//(Maximum power of 2 <= numTables) x 16.
	uint16_t		entrySelector;			//Log2(maximum power of 2 <= numTables).
	uint16_t		rangeShift;			//NumTables x 16-searchRange.
};
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct TableRecord {
	uint32_t		tag;				//4-byte identifier.
	uint32_t		checkSum;			//CheckSum for this table.
	uint32_t		offset;				//Offset from beginning of TrueType font file.
	uint32_t		length;				//Length of this table.
};
/*--------------------------------------------------------------------------*/
//仩嶲峫帒椏:乽Microsoft Typography - name - Naming Table乿(https://www.microsoft.com/typography/otspec/name.htm)
struct NamingTable {
	uint16_t		format;				//Format selector (=0 or 1).
	uint16_t		count;				//Number of name records.
	uint16_t		stringOffset;			//Offset to start of string storage (from start of table).
//	NameRecord		nameRecord[count];		//The name records where count is the number of records.
//	uint16_t		langTagCount;			//Number of language-tag records.									劍偙傟傜偺僼傿乕儖僪偼(format=1)偺応崌偩偗懚嵼偟傑偡丅
//	LangTagRecord		langTagRecord[langTagCount];	//The language-tag records where langTagCount is the number of records.					劊
//	(Variable)						//Storage for the actual string data.
};
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct LangTagRecord {
	uint16_t		length;				//Language-tag string length (in bytes)
	uint16_t		offset;				//Language-tag string offset from start of storage area (in bytes).
};
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct NameRecord {
	uint16_t		platformID;			//Platform ID.
	uint16_t		encodingID;			//Platform-specific encoding ID.
	uint16_t		languageID;			//Language ID.
	uint16_t		nameID;				//Name ID.
	uint16_t		length;				//String length (in bytes).
	uint16_t		offset;				//String offset from start of storage area (in bytes).
};
/*--------------------------------------------------------------------------*/
static char* TrueType_GetFontNameList_subr(const unsigned char* data, int ttcOffset, char* out, char* const end) {
	struct OffsetTable offsetTable;
	memcpy(&offsetTable, &data[ttcOffset + 0], sizeof(struct OffsetTable));
	//                         ~~~~~~~~~~~昁梫
	offsetTable.sfntVersion		= ntohl(offsetTable.sfntVersion);
	offsetTable.numTables		= ntohs(offsetTable.numTables);
	offsetTable.searchRange		= ntohs(offsetTable.searchRange);
	offsetTable.entrySelector	= ntohs(offsetTable.entrySelector);
	offsetTable.rangeShift		= ntohs(offsetTable.rangeShift);
	{
		int i;
		for(i = 0; i < offsetTable.numTables; i++) {
			struct TableRecord tableRecord;
			memcpy(&tableRecord, &data[ttcOffset + sizeof(struct OffsetTable) + (sizeof(struct TableRecord) * i)], sizeof(struct TableRecord));
			//                         ~~~~~~~~~~~昁梫
		//晄梫	tableRecord.tag			= ntohl(tableRecord.tag);
			tableRecord.checkSum		= ntohl(tableRecord.checkSum);
			tableRecord.offset		= ntohl(tableRecord.offset);
			tableRecord.length		= ntohl(tableRecord.length);
			if(tableRecord.tag == MAKEFOURCC('n','a','m','e')) {
				struct NamingTable namingTable;
				memcpy(&namingTable, &data[/*ttcOffset +*/ tableRecord.offset], sizeof(struct NamingTable));
				//                         ~~~~~~~~~~~~~~~晄梫丅.ttc僼傽僀儖偺応崌偱傕丄TableRecord.offset偼丄奺僼僅儞僩偺愭摢埵抲偐傜偺僆僼僙僢僩偱偼側偔丄僼傽僀儖愭摢偐傜偺僆僼僙僢僩傪帵偟偰偄傑偡丅
				namingTable.format		= ntohs(namingTable.format);
				namingTable.count		= ntohs(namingTable.count);
				namingTable.stringOffset	= ntohs(namingTable.stringOffset);
				{
					int i;
					for(i = 0; i < namingTable.count; i++) {
						struct NameRecord nameRecord;
						memcpy(&nameRecord, &data[/*ttcOffset +*/ (tableRecord.offset + sizeof(struct NamingTable)) + (sizeof(struct NameRecord) * i)], sizeof(struct NameRecord));
						//                        ~~~~~~~~~~~~~~~晄梫丅.ttc僼傽僀儖偺応崌偱傕丄TableRecord.offset偼丄奺僼僅儞僩偺愭摢埵抲偐傜偺僆僼僙僢僩偱偼側偔丄僼傽僀儖愭摢偐傜偺僆僼僙僢僩傪帵偟偰偄傑偡丅
						nameRecord.platformID		= ntohs(nameRecord.platformID);
						nameRecord.encodingID		= ntohs(nameRecord.encodingID);
						nameRecord.languageID		= ntohs(nameRecord.languageID);
						nameRecord.nameID		= ntohs(nameRecord.nameID);
						nameRecord.length		= ntohs(nameRecord.length);
						nameRecord.offset		= ntohs(nameRecord.offset);
						//仩Name IDs
						//劆Code	Meaning
						//劆0		Copyright notice.
						//劆1		Font Family name. Up to four fonts can share the Font Family name, forming a font style linking group (regular, italic, bold, bold italic - as defined by OS/2.fsSelection bit settings).
						//劆2		Font Subfamily name. The Font Subfamily name distiguishes the font in a group with the same Font Family name (name ID 1). This is assumed to address style (italic, oblique) and weight (light, bold, black, etc.). A font with no particular differences in weight or style (e.g. medium weight, not italic and fsSelection bit 6 set) should have the string 乬Regular乭 stored in this position.
						//劆3		Unique font identifier.
						//劆4		Full font name; a combination of strings 1 and 2, or a similar human-readable variant. If string 2 is "Regular", it is sometimes omitted from name ID 4.
						//劆5		Version string. Should begin with the syntax 'Version <number>.<number>' (upper case, lower case, or mixed, with a space between 乬Version乭 and the number). The string must contain a version number of the following form: one or more digits (0-9) of value less than 65,535, followed by a period, followed by one or more digits of value less than 65,535. Any character other than a digit will terminate the minor number. A character such as 乬;乭 is helpful to separate different pieces of version information. The first such match in the string can be used by installation software to compare font versions. Note that some installers may require the string to start with "Version", followed by a version number as above.
						//劆6		Postscript name for the font; Name ID 6 specifies a string which is used to invoke a PostScript language font that corresponds to this OpenType font. When translated to ASCII, the name string must be no longer than 63 characters and restricted to the printable ASCII subset, codes 33 - 126, except for the 10 characters '[', ']', '(', ')', '{', '}', '<', '>', '/', '%'. In a CFF OpenType font, there is no requirement that this name be the same as the font name in the CFF乫s Name INDEX. Thus, the same CFF may be shared among multiple font components in a Font Collection. See the 'name' table section of Recommendations for OpenType fonts "" for additional information.
						//劆7		Trademark; this is used to save any trademark notice/information for this font. Such information should be based on legal advice. This is distinctly separate from the copyright.
						//劆8		Manufacturer Name.
						//劆9		Designer; name of the designer of the typeface.
						//劆10		Description; description of the typeface. Can contain revision information, usage recommendations, history, features, etc.
						//劆11		URL Vendor; URL of font vendor (with protocol, e.g., http://, ftp://). If a unique serial number is embedded in the URL, it can be used to register the font.
						//劆12		URL Designer; URL of typeface designer (with protocol, e.g., http://, ftp://).
						//劆13		License Description; description of how the font may be legally used, or different example scenarios for licensed use. This field should be written in plain language, not legalese.
						//劆14		License Info URL; URL where additional licensing information can be found.
						//劆15		Reserved.
						//劆16		Typographic Family name: The typographic family grouping doesn't impose any constraints on the number of faces within it, in contrast with the 4-style family grouping (ID 1), which is present both for historical reasons and to express style linking groups. If name ID 16 is absent, then name ID 1 is considered to be the typographic family name. (In earlier versions of the specification, name ID 16 was known as "Preferred Family".)
						//劆17		Typographic Subfamily name: This allows font designers to specify a subfamily name within the typographic family grouping. This string must be unique within a particular typographic family. If it is absent, then name ID 2 is considered to be the typographic subfamily name. (In earlier versions of the specification, name ID 17 was known as "Preferred Subfamily".)
						//劆18		Compatible Full (Macintosh only); On the Macintosh, the menu name is constructed using the FOND resource. This usually matches the Full Name. If you want the name of the font to appear differently than the Full Name, you can insert the Compatible Full Name in ID 18.
						//劆19		Sample text; This can be the font name, or any other text that the designer thinks is the best sample to display the font in.
						//劆20		PostScript CID findfont name; Its presence in a font means that the nameID 6 holds a PostScript font name that is meant to be used with the 乬composefont乭 invocation in order to invoke the font in a PostScript interpreter. See the definition of name ID 6. The value held in the name ID 20 string is interpreted as a PostScript font name that is meant to be used with the 乬findfont乭 invocation, in order to invoke the font in a PostScript interpreter. When translated to ASCII, this name string must be restricted to the printable ASCII subset, codes 33 through 126, except for the 10 characters: '[', ']', '(', ')', '{', '}', '<', '>', '/', '%'. See "Recommendations for OTF fonts" for additional information.
						//劆21		WWS Family Name. Used to provide a WWS-conformant family name in case the entries for IDs 16 and 17 do not conform to the WWS model. (That is, in case the entry for ID 17 includes qualifiers for some attribute other than weight, width or slope.) If bit 8 of the fsSelection field is set, a WWS Family Name entry should not be needed and should not be included. Conversely, if an entry for this ID is include, bit 8 should not be set. (See OS/2 'fsSelection' field for details.) Examples of name ID 21: 乬Minion Pro Caption乭 and 乬Minion Pro Display乭. (Name ID 16 would be 乬Minion Pro乭 for these examples.)
						//劆22		WWS Subfamily Name. Used in conjunction with ID 21, this ID provides a WWS-conformant subfamily name (reflecting only weight, width and slope attributes) in case the entries for IDs 16 and 17 do not conform to the WWS model. As in the case of ID 21, use of this ID should correlate inversely with bit 8 of the fsSelection field being set. Examples of name ID 22: 乬Semibold Italic乭, 乬Bold Condensed乭. (Name ID 17 could be 乬Semibold Italic Caption乭, or 乬Bold Condensed Display乭, for example.)
						//劆23		Light Backgound Palette. This ID, if used in the CPAL table乫s Palette Labels Array, specifies that the corresponding color palette in the CPAL table is appropriate to use with the font when displaying it on a light background such as white. Name table strings for this ID specify the user interface strings associated with this palette.
						//劆24		Dark Backgound Palette. This ID, if used in the CPAL table乫s Palette Labels Array, specifies that the corresponding color palette in the CPAL table is appropriate to use with the font when displaying it on a dark background such as black. Name table strings for this ID specify the user interface strings associated with this palette.
						//劆25		Variations PostScript Name Prefix. If present in a variable font, it may be used as the family prefix in the PostScript Name Generation for Variation Fonts algorithm. The character set is restricted to ASCII-range uppercase Latin letters, lowercase Latin letters, and digits. All name strings for name ID 25 within a font, when converted to ASCII, must be identical. See Adobe Technical Note #5902: 乬PostScript Name Generation for Variation Fonts乭 for reasons to include name ID 25 in a font, and for examples. For general information on OpenType Font Variations, see the chapter, OpenType Font Variations Overview.
						if(nameRecord.nameID == 1/*Font Family name*/) {
							//仩Platform IDs, Platform-specific encoding IDs and Language IDs
							//劆Platform ID	Platform name		Platform-specific encoding IDs	Language IDs
							//劆0		Unicode			Various				Various
							//劆1		Macintosh		Script manager code		Various
							//劆2		ISO [deprecated]	ISO encoding [deprecated]	None
							//劆3		Windows			Windows encoding		Various
							//劆4		Custom			Custom				None
							if(nameRecord.platformID == 3/*Windows*/) {
								const char* p = &data[/*ttcOffset +*/ (tableRecord.offset + namingTable.stringOffset) + nameRecord.offset];	//UTF-16BE	仼Unicode暥帤楍偼UTF-16LE偱偼側偔UTF-16BE偱奿擺偝傟偰偄傑偡丅梫拲堄!!
								//                    ~~~~~~~~~~~~~~~晄梫丅.ttc僼傽僀儖偺応崌偱傕丄TableRecord.offset偼丄奺僼僅儞僩偺愭摢埵抲偐傜偺僆僼僙僢僩偱偼側偔丄僼傽僀儖愭摢偐傜偺僆僼僙僢僩傪帵偟偰偄傑偡丅
								//仩Windows platform-specific encoding IDs (platform ID= 3) 
								//劆Platform ID	Encoding ID	Description
								//劆3		0		Symbol
								//劆3		1		Unicode BMP (UCS-2)
								//劆3		2		ShiftJIS
								//劆3		3		PRC
								//劆3		4		Big5
								//劆3		5		Wansung
								//劆3		6		Johab
								//劆3		7		Reserved
								//劆3		8		Reserved
								//劆3		9		Reserved
								//劆3		10		Unicode UCS-4
								//--------------------------------------------------------------------------------------------------------------------------------------------------------------
								// * Sun Nov 27 23:52:51 JST 2016 Naoyuki Sawa
								// - 杮摉偼丄奺{platformID,encodingID}偺慻傒崌傢偣偵偮偄偰張棟偡傋偒側偺偱偡偑丄崱夞偼丄{Windows,Unicode BMP (UCS-2)}偺慻傒崌傢偣偩偗傪張棟偡傞帠偵偟傑偟偨丅
								//   {Windows,Unicode BMP (UCS-2)}埲奜偺慻傒崌傢偣偺応崌偵丄偳偺傛偆側宍幃偱僼僅儞僩柤偺暥帤楍偑奿擺偝傟偰偄傞偐丄巇條傪傑偩傛偔棟夝偱偒偰偄側偄偐傜偱偡丅
								//   偄偔偮偐偺僼僅儞僩僼傽僀儖偱帋偟偨偲偙傠丄戝掞偺僼傽僀儖偱{Windows,Unicode BMP (UCS-2)}偱偼奿擺偝傟偰偄傞傛偆側偺偱丄偙傟偩偗偱傕廩暘偩偲巚偄傑偟偨丅
								//   偦偺懠偵傕丄{Macintosh,English}(ASCII宍幃?)傗丄{Windows,Unicode UCS-4}(UTF-32BE宍幃)偱傕奿擺偝傟偰偄傞帠傕桳傞傛偆偱偡偑丄崱夞偼丄柍帇偡傞帠偵偟傑偟偨丅
								// - 仾偲巚偭偰偄偨偺偱偡偑丄偝傜偵帋偟偨強丄僔儞儃儖偩偗偺僼僅儞僩偺応崌丄{Windows,Symbol}偟偐奿擺偝傟偰偄側偄帠傕桳偭偨偺偱丄Symbol傕張棟偡傞帠偵偟傑偟偨丅
								//   杮摉偼{Windows,ShiftJIS}偵傕懳墳偟偨偄偺偱偡偑丄{Windows,ShiftJIS}偑奿擺偝傟偰偄傞僼傽僀儖偑傑偩尒晅偐傜偢丄専徹弌棃側偄偺偱丄枹懳墳偺傑傑偵偟偰偄傑偡丅
								//   偟偐偟丄乽Windows platform-specific encoding IDs (platform ID= 3)乿(https://www.microsoft.com/typography/otspec/name.htm#enc3)偵傛傞偲丄
								//   劆When building a Unicode font for Windows, the platform ID should be 3 and the encoding ID should be 1.	仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼拲栚
								//   劆When building a symbol font for Windows, the platform ID should be 3 and the encoding ID should be 0.	仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼仼拲栚
								//   劆When building a font that will be used on the Macintosh, the platform ID should be 1 and the encoding ID should be 0.
								//   偲彂偄偰偁傞偺偱丄傕偟偐偡傞偲丄{Windows,Unicode BMP (UCS-2)}偲{Windows,Symbol}偩偗偱廩暘側偺偐傕抦傟傑偣傫丅
								//--------------------------------------------------------------------------------------------------------------------------------------------------------------
								switch(nameRecord.encodingID) {
								case 0:	//Symbol
								case 1:	//Unicode BMP (UCS-2)
									{
										int i;
										for(i = 0; i < nameRecord.length; i += sizeof(wchar_t)) {
											int c = BEHALF(p);		//UTF-16BE佀UTF-16LE
											c = UnicodeToShiftJisChr(c);	//UTF-16LE佀ShiftJIS
											if(c > UCHAR_MAX) { if(out < end) { *out = c >> 8; } out++; }
											                    if(out < end) { *out = c;      } out++;
											p += sizeof(wchar_t);
										}
										if(out < end) { *out = '\0'; } out++;	//暥帤楍偺廔抂
									}
									break;
								}
							}
						}
					}
				}
			}
		}
	}
	return out;
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int TrueType_GetFontNameList(const void* _data, char* buf/*[cap]*/, int cap) {	//(buf=NULL,cap=0)壜
	const unsigned char* const data = _data;
	char*       out = buf;
	char* const end = buf + cap;
	{
		//.ttc僼傽僀儖偲壖掕偟偰丄僿僢僟傪撉傒崬傫偱傒傞丅
		struct TTCHeader ttcHeader;
		memcpy(&ttcHeader, &data[0], sizeof(struct TTCHeader));
	//晄梫	ttcHeader.TTCTag		= ntohl(ttcHeader.TTCTag);
		ttcHeader.Version		= ntohl(ttcHeader.Version);
		ttcHeader.numFonts		= ntohl(ttcHeader.numFonts);
		//.ttc僼傽僀儖偩偭偨応崌乧
		if(ttcHeader.TTCTag == MAKEFOURCC('t','t','c','f')) {
			const uint32_t* OffsetTable = (const uint32_t*)&data[sizeof(struct TTCHeader)];
			int i;
			for(i = 0; i < (int)ttcHeader.numFonts; i++) {
				int ttcOffset = ntohl(OffsetTable[i]);
				out = TrueType_GetFontNameList_subr(data, ttcOffset, out, end);
			}
		//.ttf僼傽僀儖偩偭偨応崌乧
		} else {
			out = TrueType_GetFontNameList_subr(data, 0/*ttcOffset*/, out, end);
		}
	}
	if(out == buf) { DIE(); }	//僼僅儞僩柤傪堦偮傕庢摼弌棃偰偄側偗傟偽丄僄儔乕廔椆偡傞帠偵偟偨丅僼僅儞僩柤偑彮側偔偲傕堦偮桳傞帠傪曐徹偡傞曽偑丄傾僾儕働乕僔儑儞偺幚憰偑娙扨偵側傞偲巚偭偨偐傜偱偡丅
	if(out <= end) { *out = '\0'; } out++;	//儕僗僩偺廔抂
	return out - buf;
}
