diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 55abd11d6..d9bc3b6c3 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -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 () diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index ad206511c..ac6c9e4d5 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -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 (cff, topDict.EncodingOffset); + if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; } + } + } + stringIndex = &StructAtOffset (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 fontDicts; - hb_vector_t privateDicts; - - unsigned int num_glyphs; - }; - - struct accelerator_t : accelerator_templ_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 - { - void init (hb_face_t *face) - { - SUPER::init (face); - if (blob == nullptr) return; - - const OT::cff1 *cff = this->blob->as (); - encoding = &Null(Encoding); - if (is_CID ()) - { - if (unlikely (charset == &Null(Charset))) { fini (); return; } - } - else - { - if (!is_predef_encoding ()) - { - encoding = &StructAtOffsetOrNull (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 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 fontDicts; + hb_vector_t privateDicts; + + unsigned int num_glyphs; }; + struct accelerator_t : accelerator_templ_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 {}; + 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 version; /* Version of CFF table. set to 0x0100u */ diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 96f94e4a9..a56b8fd3f 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -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,