11 * all copies of this software. 12 * 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 * DAMAGE. 18 * 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 * 25 * Red Hat Author(s): Behdad Esfahbod 26 * Google Author(s): Behdad Esfahbod 27 */ 28 29 #include "hb-private.hh" 30 31 #include "hb-ot-layout-private.hh" 32 33 #include "hb-font-private.hh" 34 #include "hb-open-file-private.hh" 35 #include "hb-ot-head-table.hh" 36 #include "hb-ot-maxp-table.hh" 37 38 #include <string.h> 39 40 41 /* 42 * hb_face_t 43 */ 44 45 const hb_face_t _hb_face_nil = { 46 HB_OBJECT_HEADER_STATIC, 47 48 true, /* immutable */ 49 50 NULL, /* reference_table_func */ 51 NULL, /* user_data */ 52 NULL, /* destroy */ 53 54 0, /* index */ 55 1000, /* upem */ 56 0, /* num_glyphs */ 57 58 { 59 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 60 #include "hb-shaper-list.hh" 61 #undef HB_SHAPER_IMPLEMENT 62 }, 63 64 NULL, /* shape_plans */ 65 }; 66 67 68 /** 69 * hb_face_create_for_tables: 70 * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): 71 * @user_data: 72 * @destroy: 73 * 74 * 75 * 76 * Return value: (transfer full) 77 * 78 * Since: 0.9.2 79 **/ 80 hb_face_t * 81 hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, 82 void *user_data, 83 hb_destroy_func_t destroy) 84 { 96 97 face->upem = 0; 98 face->num_glyphs = (unsigned int) -1; 99 100 return face; 101 } 102 103 104 typedef struct hb_face_for_data_closure_t { 105 hb_blob_t *blob; 106 unsigned int index; 107 } hb_face_for_data_closure_t; 108 109 static hb_face_for_data_closure_t * 110 _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) 111 { 112 hb_face_for_data_closure_t *closure; 113 114 closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t)); 115 if (unlikely (!closure)) 116 return NULL; 117 118 closure->blob = blob; 119 closure->index = index; 120 121 return closure; 122 } 123 124 static void 125 _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure) 126 { 127 hb_blob_destroy (closure->blob); 128 free (closure); 129 } 130 131 static hb_blob_t * 132 _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) 133 { 134 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; 135 136 if (tag == HB_TAG_NONE) 137 return hb_blob_reference (data->blob); 138 139 const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob); 140 const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); 141 142 const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag); 143 144 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length); 145 146 return blob; 147 } 148 149 /** 156 * Return value: (transfer full): 157 * 158 * Since: 0.9.2 159 **/ 160 hb_face_t * 161 hb_face_create (hb_blob_t *blob, 162 unsigned int index) 163 { 164 hb_face_t *face; 165 166 if (unlikely (!blob)) 167 blob = hb_blob_get_empty (); 168 169 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); 170 171 if (unlikely (!closure)) 172 return hb_face_get_empty (); 173 174 face = hb_face_create_for_tables (_hb_face_for_data_reference_table, 175 closure, 176 (hb_destroy_func_t) _hb_face_for_data_closure_destroy); 177 178 hb_face_set_index (face, index); 179 180 return face; 181 } 182 183 /** 184 * hb_face_get_empty: 185 * 186 * 187 * 188 * Return value: (transfer full) 189 * 190 * Since: 0.9.2 191 **/ 192 hb_face_t * 193 hb_face_get_empty (void) 194 { 195 return const_cast<hb_face_t *> (&_hb_face_nil); 196 } 197 198 459 * 460 * Return value: 461 * 462 * Since: 0.9.7 463 **/ 464 unsigned int 465 hb_face_get_glyph_count (hb_face_t *face) 466 { 467 return face->get_num_glyphs (); 468 } 469 470 void 471 hb_face_t::load_num_glyphs (void) const 472 { 473 hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp)); 474 const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob); 475 num_glyphs = maxp_table->get_num_glyphs (); 476 hb_blob_destroy (maxp_blob); 477 } 478 479 | 11 * all copies of this software. 12 * 13 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 14 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 15 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 16 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 17 * DAMAGE. 18 * 19 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 20 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 22 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 24 * 25 * Red Hat Author(s): Behdad Esfahbod 26 * Google Author(s): Behdad Esfahbod 27 */ 28 29 #include "hb-private.hh" 30 31 #include "hb-face-private.hh" 32 #include "hb-open-file-private.hh" 33 #include "hb-ot-head-table.hh" 34 #include "hb-ot-maxp-table.hh" 35 36 37 /* 38 * hb_face_t 39 */ 40 41 const hb_face_t _hb_face_nil = { 42 HB_OBJECT_HEADER_STATIC, 43 44 true, /* immutable */ 45 46 nullptr, /* reference_table_func */ 47 nullptr, /* user_data */ 48 nullptr, /* destroy */ 49 50 0, /* index */ 51 1000, /* upem */ 52 0, /* num_glyphs */ 53 54 { 55 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, 56 #include "hb-shaper-list.hh" 57 #undef HB_SHAPER_IMPLEMENT 58 }, 59 60 nullptr, /* shape_plans */ 61 }; 62 63 64 /** 65 * hb_face_create_for_tables: 66 * @reference_table_func: (closure user_data) (destroy destroy) (scope notified): 67 * @user_data: 68 * @destroy: 69 * 70 * 71 * 72 * Return value: (transfer full) 73 * 74 * Since: 0.9.2 75 **/ 76 hb_face_t * 77 hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, 78 void *user_data, 79 hb_destroy_func_t destroy) 80 { 92 93 face->upem = 0; 94 face->num_glyphs = (unsigned int) -1; 95 96 return face; 97 } 98 99 100 typedef struct hb_face_for_data_closure_t { 101 hb_blob_t *blob; 102 unsigned int index; 103 } hb_face_for_data_closure_t; 104 105 static hb_face_for_data_closure_t * 106 _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) 107 { 108 hb_face_for_data_closure_t *closure; 109 110 closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t)); 111 if (unlikely (!closure)) 112 return nullptr; 113 114 closure->blob = blob; 115 closure->index = index; 116 117 return closure; 118 } 119 120 #ifdef __SUNPRO_CC 121 extern "C" { 122 #endif 123 static void 124 _hb_face_for_data_closure_destroy (void *data) 125 { 126 hb_face_for_data_closure_t *closure = (hb_face_for_data_closure_t *) data; 127 128 hb_blob_destroy (closure->blob); 129 free (closure); 130 } 131 #ifdef __SUNPRO_CC 132 } 133 #endif 134 135 static hb_blob_t * 136 _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) 137 { 138 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data; 139 140 if (tag == HB_TAG_NONE) 141 return hb_blob_reference (data->blob); 142 143 const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob); 144 const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); 145 146 const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag); 147 148 hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length); 149 150 return blob; 151 } 152 153 /** 160 * Return value: (transfer full): 161 * 162 * Since: 0.9.2 163 **/ 164 hb_face_t * 165 hb_face_create (hb_blob_t *blob, 166 unsigned int index) 167 { 168 hb_face_t *face; 169 170 if (unlikely (!blob)) 171 blob = hb_blob_get_empty (); 172 173 hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); 174 175 if (unlikely (!closure)) 176 return hb_face_get_empty (); 177 178 face = hb_face_create_for_tables (_hb_face_for_data_reference_table, 179 closure, 180 _hb_face_for_data_closure_destroy); 181 182 face->index = index; 183 184 return face; 185 } 186 187 /** 188 * hb_face_get_empty: 189 * 190 * 191 * 192 * Return value: (transfer full) 193 * 194 * Since: 0.9.2 195 **/ 196 hb_face_t * 197 hb_face_get_empty (void) 198 { 199 return const_cast<hb_face_t *> (&_hb_face_nil); 200 } 201 202 463 * 464 * Return value: 465 * 466 * Since: 0.9.7 467 **/ 468 unsigned int 469 hb_face_get_glyph_count (hb_face_t *face) 470 { 471 return face->get_num_glyphs (); 472 } 473 474 void 475 hb_face_t::load_num_glyphs (void) const 476 { 477 hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp)); 478 const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob); 479 num_glyphs = maxp_table->get_num_glyphs (); 480 hb_blob_destroy (maxp_blob); 481 } 482 483 /** 484 * hb_face_get_table_tags: 485 * @face: a face. 486 * 487 * Retrieves table tags for a face, if possible. 488 * 489 * Return value: total number of tables, or 0 if not possible to list. 490 * 491 * Since: 1.6.0 492 **/ 493 unsigned int 494 hb_face_get_table_tags (hb_face_t *face, 495 unsigned int start_offset, 496 unsigned int *table_count, /* IN/OUT */ 497 hb_tag_t *table_tags /* OUT */) 498 { 499 if (face->destroy != _hb_face_for_data_closure_destroy) 500 { 501 if (table_count) 502 *table_count = 0; 503 return 0; 504 } 505 506 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) face->user_data; 507 508 const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob); 509 const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index); 510 511 return ot_face.get_table_tags (start_offset, table_count, table_tags); 512 } |