src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-post-table.hh
changeset 50826 f5b95be8b6e2
parent 50352 25db2c8f3cf8
child 54232 7c11a7cc7c1d
equal deleted inserted replaced
50825:aa0a35b071fb 50826:f5b95be8b6e2
    27 #ifndef HB_OT_POST_TABLE_HH
    27 #ifndef HB_OT_POST_TABLE_HH
    28 #define HB_OT_POST_TABLE_HH
    28 #define HB_OT_POST_TABLE_HH
    29 
    29 
    30 #include "hb-open-type-private.hh"
    30 #include "hb-open-type-private.hh"
    31 #include "hb-dsalgs.hh"
    31 #include "hb-dsalgs.hh"
       
    32 #include "hb-subset-plan.hh"
    32 
    33 
    33 #define HB_STRING_ARRAY_NAME format1_names
    34 #define HB_STRING_ARRAY_NAME format1_names
    34 #define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh"
    35 #define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh"
    35 #include "hb-string-array.hh"
    36 #include "hb-string-array.hh"
    36 #undef HB_STRING_ARRAY_LIST
    37 #undef HB_STRING_ARRAY_LIST
    37 #undef HB_STRING_ARRAY_NAME
    38 #undef HB_STRING_ARRAY_NAME
    38 
    39 
    39 #define NUM_FORMAT1_NAMES 258
    40 #define NUM_FORMAT1_NAMES 258
    40 
    41 
    41 namespace OT {
       
    42 
       
    43 
       
    44 /*
    42 /*
    45  * post -- PostScript
    43  * post -- PostScript
       
    44  * https://docs.microsoft.com/en-us/typography/opentype/spec/post
    46  */
    45  */
    47 
       
    48 #define HB_OT_TAG_post HB_TAG('p','o','s','t')
    46 #define HB_OT_TAG_post HB_TAG('p','o','s','t')
       
    47 
       
    48 
       
    49 namespace OT {
    49 
    50 
    50 
    51 
    51 struct postV2Tail
    52 struct postV2Tail
    52 {
    53 {
    53   inline bool sanitize (hb_sanitize_context_t *c) const
    54   inline bool sanitize (hb_sanitize_context_t *c) const
    80       return_trace (v2.sanitize (c));
    81       return_trace (v2.sanitize (c));
    81     }
    82     }
    82     return_trace (true);
    83     return_trace (true);
    83   }
    84   }
    84 
    85 
       
    86   inline bool subset (hb_subset_plan_t *plan) const
       
    87   {
       
    88     unsigned int post_prime_length;
       
    89     hb_blob_t *post_blob = OT::Sanitizer<post>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_post));
       
    90     hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::static_size);
       
    91     post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
       
    92     hb_blob_destroy (post_blob);
       
    93 
       
    94     if (unlikely (!post_prime || post_prime_length != post::static_size))
       
    95     {
       
    96       hb_blob_destroy (post_prime_blob);
       
    97       DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length);
       
    98       return false;
       
    99     }
       
   100 
       
   101     post_prime->version.major.set (3); // Version 3 does not have any glyph names.
       
   102     bool result = plan->add_table (HB_OT_TAG_post, post_prime_blob);
       
   103     hb_blob_destroy (post_prime_blob);
       
   104 
       
   105     return result;
       
   106   }
       
   107 
    85   struct accelerator_t
   108   struct accelerator_t
    86   {
   109   {
    87     inline void init (hb_face_t *face)
   110     inline void init (hb_face_t *face)
    88     {
   111     {
       
   112       index_to_offset.init ();
       
   113 
    89       blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post));
   114       blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post));
    90       const post *table = Sanitizer<post>::lock_instance (blob);
   115       const post *table = blob->as<post> ();
    91       unsigned int table_length = hb_blob_get_length (blob);
   116       unsigned int table_length = blob->length;
    92 
   117 
    93       version = table->version.to_int ();
   118       version = table->version.to_int ();
    94       index_to_offset.init ();
       
    95       if (version != 0x00020000)
   119       if (version != 0x00020000)
    96         return;
   120         return;
    97 
   121 
    98       const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
   122       const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
    99 
   123 
   100       glyphNameIndex = &v2.glyphNameIndex;
   124       glyphNameIndex = &v2.glyphNameIndex;
   101       pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
   125       pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
   102 
   126 
   103       const uint8_t *end = (uint8_t *) table + table_length;
   127       const uint8_t *end = (uint8_t *) table + table_length;
   104       for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data)
   128       for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data)
   105       {
   129         index_to_offset.push (data - pool);
   106         uint32_t *offset = index_to_offset.push ();
       
   107         if (unlikely (!offset))
       
   108           break;
       
   109         *offset = data - pool;
       
   110       }
       
   111     }
   130     }
   112     inline void fini (void)
   131     inline void fini (void)
   113     {
   132     {
   114       index_to_offset.finish ();
   133       index_to_offset.fini ();
   115       free (gids_sorted_by_name);
   134       free (gids_sorted_by_name);
   116     }
   135     }
   117 
   136 
   118     inline bool get_glyph_name (hb_codepoint_t glyph,
   137     inline bool get_glyph_name (hb_codepoint_t glyph,
   119                                 char *buf, unsigned int buf_len) const
   138                                 char *buf, unsigned int buf_len) const
   120     {
   139     {
   121       hb_string_t s = find_glyph_name (glyph);
   140       hb_bytes_t s = find_glyph_name (glyph);
   122       if (!s.len)
   141       if (!s.len)
   123         return false;
   142         return false;
   124       if (!buf_len)
   143       if (!buf_len)
   125         return true;
   144         return true;
   126       if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
   145       if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
   160           free (gids);
   179           free (gids);
   161           goto retry;
   180           goto retry;
   162         }
   181         }
   163       }
   182       }
   164 
   183 
   165       hb_string_t st (name, len);
   184       hb_bytes_t st (name, len);
   166       const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
   185       const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
   167       if (gid)
   186       if (gid)
   168       {
   187       {
   169         *glyph = *gid;
   188         *glyph = *gid;
   170         return true;
   189         return true;
   195     }
   214     }
   196 
   215 
   197     static inline int cmp_key (const void *pk, const void *po, void *arg)
   216     static inline int cmp_key (const void *pk, const void *po, void *arg)
   198     {
   217     {
   199       const accelerator_t *thiz = (const accelerator_t *) arg;
   218       const accelerator_t *thiz = (const accelerator_t *) arg;
   200       const hb_string_t *key = (const hb_string_t *) pk;
   219       const hb_bytes_t *key = (const hb_bytes_t *) pk;
   201       uint16_t o = * (const uint16_t *) po;
   220       uint16_t o = * (const uint16_t *) po;
   202       return thiz->find_glyph_name (o).cmp (*key);
   221       return thiz->find_glyph_name (o).cmp (*key);
   203     }
   222     }
   204 
   223 
   205     inline hb_string_t find_glyph_name (hb_codepoint_t glyph) const
   224     inline hb_bytes_t find_glyph_name (hb_codepoint_t glyph) const
   206     {
   225     {
   207       if (version == 0x00010000)
   226       if (version == 0x00010000)
   208       {
   227       {
   209         if (glyph >= NUM_FORMAT1_NAMES)
   228         if (glyph >= NUM_FORMAT1_NAMES)
   210           return hb_string_t ();
   229           return hb_bytes_t ();
   211 
   230 
   212         return format1_names (glyph);
   231         return format1_names (glyph);
   213       }
   232       }
   214 
   233 
   215       if (version != 0x00020000 || glyph >= glyphNameIndex->len)
   234       if (version != 0x00020000 || glyph >= glyphNameIndex->len)
   216         return hb_string_t ();
   235         return hb_bytes_t ();
   217 
   236 
   218       unsigned int index = glyphNameIndex->array[glyph];
   237       unsigned int index = glyphNameIndex->arrayZ[glyph];
   219       if (index < NUM_FORMAT1_NAMES)
   238       if (index < NUM_FORMAT1_NAMES)
   220         return format1_names (index);
   239         return format1_names (index);
   221       index -= NUM_FORMAT1_NAMES;
   240       index -= NUM_FORMAT1_NAMES;
   222 
   241 
   223       if (index >= index_to_offset.len)
   242       if (index >= index_to_offset.len)
   224         return hb_string_t ();
   243         return hb_bytes_t ();
   225       unsigned int offset = index_to_offset.array[index];
   244       unsigned int offset = index_to_offset.arrayZ[index];
   226 
   245 
   227       const uint8_t *data = pool + offset;
   246       const uint8_t *data = pool + offset;
   228       unsigned int name_length = *data;
   247       unsigned int name_length = *data;
   229       data++;
   248       data++;
   230 
   249 
   231       return hb_string_t ((const char *) data, name_length);
   250       return hb_bytes_t ((const char *) data, name_length);
   232     }
   251     }
   233 
   252 
   234     private:
   253     private:
   235     hb_blob_t *blob;
   254     hb_blob_t *blob;
   236     uint32_t version;
   255     uint32_t version;
   237     const ArrayOf<HBUINT16> *glyphNameIndex;
   256     const ArrayOf<HBUINT16> *glyphNameIndex;
   238     hb_prealloced_array_t<uint32_t, 1> index_to_offset;
   257     hb_vector_t<uint32_t, 1> index_to_offset;
   239     const uint8_t *pool;
   258     const uint8_t *pool;
   240     mutable uint16_t *gids_sorted_by_name;
   259     mutable uint16_t *gids_sorted_by_name;
   241   };
   260   };
   242 
   261 
   243   public:
   262   public: