add cff1::get_glyph_name

This commit is contained in:
blueshade7 2019-11-16 18:20:16 -08:00 committed by Behdad Esfahbod
parent d5338ba189
commit 7b49042ef4
3 changed files with 144 additions and 55 deletions

View File

@ -125,6 +125,67 @@ static const uint8_t standard_encoding_to_sid [] =
0, 144, 0, 0, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0
};
/* SID to standard string */
static const char *sid_to_standard_string [] =
{
".notdef", "space", "exclam", "quotedbl", "numbersign", "dollar", "percent",
"ampersand", "quoteright", "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", "quoteleft", "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", "exclamdown", "cent",
"sterling", "fraction", "yen", "florin", "section", "currency", "quotesingle",
"quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", "fl", "endash",
"dagger", "daggerdbl", "periodcentered", "paragraph", "bullet", "quotesinglbase", "quotedblbase",
"quotedblright", "guillemotright", "ellipsis", "perthousand", "questiondown", "grave", "acute",
"circumflex", "tilde", "macron", "breve", "dotaccent", "dieresis", "ring",
"cedilla", "hungarumlaut", "ogonek", "caron", "emdash", "AE", "ordfeminine",
"Lslash", "Oslash", "OE", "ordmasculine", "ae", "dotlessi", "lslash",
"oslash", "oe", "germandbls", "onesuperior", "logicalnot", "mu", "trademark",
"Eth", "onehalf", "plusminus", "Thorn", "onequarter", "divide", "brokenbar",
"degree", "thorn", "threequarters", "twosuperior", "registered", "minus", "eth",
"multiply", "threesuperior", "copyright", "Aacute", "Acircumflex", "Adieresis", "Agrave",
"Aring", "Atilde", "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave",
"Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde", "Oacute", "Ocircumflex",
"Odieresis", "Ograve", "Otilde", "Scaron", "Uacute", "Ucircumflex", "Udieresis",
"Ugrave", "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex", "adieresis",
"agrave", "aring", "atilde", "ccedilla", "eacute", "ecircumflex", "edieresis",
"egrave", "iacute", "icircumflex", "idieresis", "igrave", "ntilde", "oacute",
"ocircumflex", "odieresis", "ograve", "otilde", "scaron", "uacute", "ucircumflex",
"udieresis", "ugrave", "yacute", "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall",
"dollaroldstyle", "dollarsuperior", "ampersandsmall", "Acutesmall", "parenleftsuperior", "parenrightsuperior", "twodotenleader",
"onedotenleader", "zerooldstyle", "oneoldstyle", "twooldstyle", "threeoldstyle", "fouroldstyle", "fiveoldstyle",
"sixoldstyle", "sevenoldstyle", "eightoldstyle", "nineoldstyle", "commasuperior", "threequartersemdash", "periodsuperior",
"questionsmall", "asuperior", "bsuperior", "centsuperior", "dsuperior", "esuperior", "isuperior",
"lsuperior", "msuperior", "nsuperior", "osuperior", "rsuperior", "ssuperior", "tsuperior",
"ff", "ffi", "ffl", "parenleftinferior", "parenrightinferior", "Circumflexsmall", "hyphensuperior",
"Gravesmall", "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
"Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall", "Msmall",
"Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall", "Ssmall", "Tsmall",
"Usmall", "Vsmall", "Wsmall", "Xsmall", "Ysmall", "Zsmall", "colonmonetary",
"onefitted", "rupiah", "Tildesmall", "exclamdownsmall", "centoldstyle", "Lslashsmall", "Scaronsmall",
"Zcaronsmall", "Dieresissmall", "Brevesmall", "Caronsmall", "Dotaccentsmall", "Macronsmall", "figuredash",
"hypheninferior", "Ogoneksmall", "Ringsmall", "Cedillasmall", "questiondownsmall", "oneeighth", "threeeighths",
"fiveeighths", "seveneighths", "onethird", "twothirds", "zerosuperior", "foursuperior", "fivesuperior",
"sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", "zeroinferior", "oneinferior", "twoinferior",
"threeinferior", "fourinferior", "fiveinferior", "sixinferior", "seveninferior", "eightinferior", "nineinferior",
"centinferior", "dollarinferior", "periodinferior", "commainferior", "Agravesmall", "Aacutesmall", "Acircumflexsmall",
"Atildesmall", "Adieresissmall", "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall", "Eacutesmall",
"Ecircumflexsmall", "Edieresissmall", "Igravesmall", "Iacutesmall", "Icircumflexsmall", "Idieresissmall", "Ethsmall",
"Ntildesmall", "Ogravesmall", "Oacutesmall", "Ocircumflexsmall", "Otildesmall", "Odieresissmall", "OEsmall",
"Oslashsmall", "Ugravesmall", "Uacutesmall", "Ucircumflexsmall", "Udieresissmall", "Yacutesmall", "Thornsmall",
"Ydieresissmall", "001.000", "001.001", "001.002", "001.003", "Black", "Bold",
"Book", "Light", "Medium", "Regular", "Roman", "Semibold"
};
hb_codepoint_t OT::cff1::lookup_standard_encoding_for_code (hb_codepoint_t sid)
{
if (sid < ARRAY_LENGTH (standard_encoding_to_code))
@ -165,6 +226,14 @@ hb_codepoint_t OT::cff1::lookup_standard_encoding_for_sid (hb_codepoint_t code)
return CFF_UNDEF_SID;
}
const char *OT::cff1::lookup_standard_string_for_sid (hb_codepoint_t sid)
{
if (sid < ARRAY_LENGTH (sid_to_standard_string))
return sid_to_standard_string[sid];
else
return "";
}
struct bounds_t
{
void init ()

View File

@ -40,6 +40,7 @@ namespace CFF {
#define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ')
#define CFF_UNDEF_SID CFF_UNDEF_CODE
#define HB_CFF_STD_STR_COUNT 391
enum EncodingID { StandardEncoding = 0, ExpertEncoding = 1 };
enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 };
@ -1076,6 +1077,20 @@ struct cff1
fdSelect = &Null(CFF1FDSelect);
}
encoding = &Null(Encoding);
if (is_CID ())
{
if (unlikely (charset == &Null(Charset))) { fini (); return; }
}
else
{
if (!is_predef_encoding ())
{
encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset);
if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; }
}
}
stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ());
if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc))
{ fini (); return; }
@ -1172,57 +1187,6 @@ struct cff1
return 0;
}
protected:
hb_blob_t *blob;
hb_sanitize_context_t sc;
public:
const Charset *charset;
const CFF1NameIndex *nameIndex;
const CFF1TopDictIndex *topDictIndex;
const CFF1StringIndex *stringIndex;
const CFF1Subrs *globalSubrs;
const CFF1CharStrings *charStrings;
const CFF1FDArray *fdArray;
const CFF1FDSelect *fdSelect;
unsigned int fdCount;
cff1_top_dict_values_t topDict;
hb_vector_t<cff1_font_dict_values_t> fontDicts;
hb_vector_t<PRIVDICTVAL> privateDicts;
unsigned int num_glyphs;
};
struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
{
HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
};
struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t>
{
void init (hb_face_t *face)
{
SUPER::init (face);
if (blob == nullptr) return;
const OT::cff1 *cff = this->blob->as<OT::cff1> ();
encoding = &Null(Encoding);
if (is_CID ())
{
if (unlikely (charset == &Null(Charset))) { fini (); return; }
}
else
{
if (!is_predef_encoding ())
{
encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset);
if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; }
}
}
}
bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
@ -1274,12 +1238,63 @@ struct cff1
}
}
const Encoding *encoding;
protected:
hb_blob_t *blob;
hb_sanitize_context_t sc;
private:
typedef accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> SUPER;
public:
const Encoding *encoding;
const Charset *charset;
const CFF1NameIndex *nameIndex;
const CFF1TopDictIndex *topDictIndex;
const CFF1StringIndex *stringIndex;
const CFF1Subrs *globalSubrs;
const CFF1CharStrings *charStrings;
const CFF1FDArray *fdArray;
const CFF1FDSelect *fdSelect;
unsigned int fdCount;
cff1_top_dict_values_t topDict;
hb_vector_t<cff1_font_dict_values_t> fontDicts;
hb_vector_t<PRIVDICTVAL> privateDicts;
unsigned int num_glyphs;
};
struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
{
bool get_glyph_name (hb_codepoint_t glyph,
char *buf, unsigned int buf_len) const
{
if (!buf) return true;
hb_codepoint_t sid = glyph_to_sid (glyph);
byte_str_t byte_str;
const char *str;
size_t str_len;
if (sid < HB_CFF_STD_STR_COUNT)
{
str = lookup_standard_string_for_sid (sid);
str_len = strlen(str);
}
else
{
byte_str = (*stringIndex)[sid - HB_CFF_STD_STR_COUNT ];
str = (const char *)byte_str.arrayZ;
str_len = byte_str.length;
}
if (!str_len) return false;
unsigned int len = hb_min (buf_len - 1, str_len);
strncpy (buf, (const char*)str, len);
buf[len] = '\0';
return true;
}
HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
};
struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> {};
bool subset (hb_subset_plan_t *plan) const
{
hb_blob_t *cff_prime = nullptr;
@ -1304,6 +1319,7 @@ struct cff1
HB_INTERNAL static hb_codepoint_t lookup_expert_charset_for_sid (hb_codepoint_t glyph);
HB_INTERNAL static hb_codepoint_t lookup_expert_subset_charset_for_sid (hb_codepoint_t glyph);
HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_sid (hb_codepoint_t code);
HB_INTERNAL static const char *lookup_standard_string_for_sid (hb_codepoint_t sid);
public:
FixedVersion<HBUINT8> version; /* Version of CFF table. set to 0x0100u */

View File

@ -210,7 +210,11 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
return ot_face->post->get_glyph_name (glyph, name, size);
hb_bool_t ret = ot_face->post->get_glyph_name (glyph, name, size);
#ifndef HB_NO_OT_FONT_CFF
if (!ret) ret = ot_face->cff1->get_glyph_name (glyph, name, size);
#endif
return ret;
}
static hb_bool_t
hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,