2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
10 #include FT_TRUETYPE_IDS_H
13 #include "hb-private.h"
14 #include "hb-atomic-private.h"
15 #include "hb-shaper-private.h"
16 #include "hb-face-private.h"
17 #include "hb-blob-private.h"
18 #include "hb-open-file-private.h"
20 void hb_face_make_immutable(hb_face_t
* face
)
22 if (hb_atomic_int32_get(&face
->ref_cnt
) == REF_CNT_INVALID_VAL
)
25 face
->immutable
= TRUE
;
28 hb_face_t
*hb_face_reference(hb_face_t
* face
)
30 if (hb_atomic_int32_get(&face
->ref_cnt
) != REF_CNT_INVALID_VAL
)
31 hb_atomic_int32_add(&face
->ref_cnt
, 1);
35 /*XXX:should go in lib "global init"*/
36 static hb_face_t hb_face_nil
= {
37 REF_CNT_INVALID_VAL
, /*ref_cnt */
44 HB_SHAPER_DATA_INVALID
,
47 HB_SHAPER_DATA_INVALID
,
49 HB_SHAPER_DATA_INVALID
/*fallback */
51 NULL
, /*shape_plans */
55 NULL
/*reference_table_func */
58 hb_face_t
*hb_face_get_empty(void)
63 void hb_face_set_index(hb_face_t
* face
, unsigned index
)
65 if (hb_atomic_int32_get(&face
->ref_cnt
) == REF_CNT_INVALID_VAL
)
71 void hb_face_set_upem(hb_face_t
* face
, unsigned upem
)
73 if (hb_atomic_int32_get(&face
->ref_cnt
) == REF_CNT_INVALID_VAL
)
79 hb_face_t
*hb_face_create_for_tables(hb_reference_table_func_t
80 reference_table_func
, void *user_data
,
81 hb_destroy_func_t destroy
)
85 face
= calloc(1, sizeof(*face
));
86 if (!reference_table_func
|| !face
) {
91 return hb_face_get_empty();
93 hb_atomic_int32_set(&face
->ref_cnt
, 1);
95 face
->reference_table_func
= reference_table_func
;
96 face
->user_data
= user_data
;
97 face
->destroy
= destroy
;
100 face
->num_glyphs
= (unsigned)-1;
104 typedef struct hb_face_for_data_closure_t
{
107 } hb_face_for_data_closure_t
;
109 static hb_face_for_data_closure_t
*hb_face_for_data_closure_create(hb_blob_t
*
114 hb_face_for_data_closure_t
*closure
;
116 closure
= malloc(sizeof(*closure
));
120 closure
->blob
= blob
;
121 closure
->index
= index
;
125 static void hb_face_for_data_closure_destroy(hb_face_for_data_closure_t
*
128 hb_blob_destroy(closure
->blob
);
132 static hb_blob_t
*hb_face_for_data_reference_table(hb_face_t
* face HB_UNUSED
,
136 hb_face_for_data_closure_t
*data
;
137 struct ot_fnt_file
*ot_fnt_file
;
138 struct ot_fnt_face
*ot_fnt_face
;
139 struct ot_tbl
*ot_tbl
;
142 data
= (hb_face_for_data_closure_t
*) user_data
;
143 if (tag
== HB_TAG_NONE
)
144 return hb_blob_reference(data
->blob
);
146 /*XXX:carefull, we don't use a "null" object like original code
148 ot_fnt_file
= hb_blob_lock_instance(data
->blob
);
149 ot_fnt_face
= ot_fnt_file_get_face(ot_fnt_file
, data
->index
);
150 ot_tbl
= ot_fnt_face_get_tbl_by_tag(ot_fnt_face
, tag
);
152 /*XXX:without "null" object return the empty blob */
154 return hb_blob_get_empty();
155 blob
= hb_blob_create_sub_blob(data
->blob
, ot_tbl
->of
, ot_tbl
->len
);
159 hb_face_t
*hb_face_create(hb_blob_t
* blob
, unsigned index
)
162 hb_face_for_data_closure_t
*closure
;
164 if (!blob
|| !hb_blob_get_length(blob
))
165 return hb_face_get_empty();
168 hb_face_for_data_closure_create(hb_blob_reference(blob
), index
);
171 return hb_face_get_empty();
174 hb_face_create_for_tables(hb_face_for_data_reference_table
, closure
,
176 hb_face_for_data_closure_destroy
);
178 hb_face_set_index(face
, index
);
182 void hb_face_destroy(hb_face_t
* face
)
186 if (hb_atomic_int32_get(&face
->ref_cnt
) == REF_CNT_INVALID_VAL
)
188 hb_atomic_int32_add(&face
->ref_cnt
, -1);
189 if (hb_atomic_int32_get(&face
->ref_cnt
) > 0)
191 hb_atomic_int32_set(&face
->ref_cnt
, REF_CNT_INVALID_VAL
);
193 #ifdef HAVE_GRAPHITE2
194 if (face
->shaper_data
.graphite2
195 && face
->shaper_data
.graphite2
!= HB_SHAPER_DATA_INVALID
196 && face
->shaper_data
.graphite2
!= HB_SHAPER_DATA_SUCCEEDED
)
197 hb_graphite2_shaper_face_data_destroy(face
->shaper_data
.
201 if (face
->shaper_data
.ot
202 && face
->shaper_data
.ot
!= HB_SHAPER_DATA_INVALID
203 && face
->shaper_data
.ot
!= HB_SHAPER_DATA_SUCCEEDED
)
204 hb_ot_shaper_face_data_destroy(face
->shaper_data
.ot
);
206 if (face
->shaper_data
.fallback
207 && face
->shaper_data
.fallback
!= HB_SHAPER_DATA_INVALID
208 && face
->shaper_data
.fallback
!= HB_SHAPER_DATA_SUCCEEDED
)
209 hb_fallback_shaper_face_data_destroy(face
->shaper_data
.
213 face
->destroy(face
->user_data
);