1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
8 #include FT_TRUETYPE_IDS_H
11 #include "hb-private.h"
12 #include "hb-atomic-private.h"
13 #include "hb-shaper-private.h"
14 #include "hb-face-private.h"
15 #include "hb-blob-private.h"
16 #include "hb-open-file-private.h"
19 hb_face_make_immutable(hb_face_t
*face
)
21 if (hb_atomic_int32_get(&face
->ref_cnt
) == REF_CNT_INVALID_VAL
)
24 face
->immutable
= TRUE
;
28 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 static hb_face_t hb_face_nil
= {
36 REF_CNT_INVALID_VAL
,//ref_cnt
43 HB_SHAPER_DATA_INVALID
,
46 HB_SHAPER_DATA_INVALID
,
48 HB_SHAPER_DATA_INVALID
//fallback
54 NULL
//reference_table_func
58 hb_face_get_empty(void)
64 hb_face_set_index(hb_face_t
*face
, unsigned index
)
66 if (hb_atomic_int32_get(&face
->ref_cnt
) == REF_CNT_INVALID_VAL
)
73 hb_face_set_upem(hb_face_t
*face
,
76 if (hb_atomic_int32_get(&face
->ref_cnt
) == REF_CNT_INVALID_VAL
)
83 hb_face_create_for_tables(hb_reference_table_func_t reference_table_func
,
85 hb_destroy_func_t destroy
)
87 hb_face_t
*face
= calloc(1, sizeof(*face
));
88 if (!reference_table_func
|| !face
) {
93 return hb_face_get_empty();
95 hb_atomic_int32_set(&face
->ref_cnt
, 1);
97 face
->reference_table_func
= reference_table_func
;
98 face
->user_data
= user_data
;
99 face
->destroy
= destroy
;
102 face
->num_glyphs
= (unsigned)-1;
106 typedef struct hb_face_for_data_closure_t
{
109 } hb_face_for_data_closure_t
;
111 static hb_face_for_data_closure_t
*
112 hb_face_for_data_closure_create(hb_blob_t
*blob
, unsigned index
)
114 hb_face_for_data_closure_t
*closure
;
116 closure
= malloc(sizeof(*closure
));
120 closure
->blob
= blob
;
121 closure
->index
= index
;
126 hb_face_for_data_closure_destroy(hb_face_for_data_closure_t
*closure
)
128 hb_blob_destroy(closure
->blob
);
133 hb_face_for_data_reference_table(hb_face_t
*face HB_UNUSED
,
137 hb_face_for_data_closure_t
*data
= (hb_face_for_data_closure_t
*)user_data
;
139 if (tag
== HB_TAG_NONE
)
140 return hb_blob_reference(data
->blob
);
142 //XXX:carefull, we don't use a "null" object like original code
144 struct ot_fnt_file
*ot_fnt_file
= hb_blob_lock_instance(data
->blob
);
145 struct ot_fnt_face
*ot_fnt_face
= ot_fnt_file_get_face(ot_fnt_file
,
147 struct ot_tbl
*ot_tbl
= ot_fnt_face_get_tbl_by_tag(ot_fnt_face
, tag
);
149 //XXX:without "null" object return the empty blob
151 return hb_blob_get_empty();
152 hb_blob_t
*blob
= hb_blob_create_sub_blob(data
->blob
, ot_tbl
->of
,
158 hb_face_create(hb_blob_t
*blob
,
163 if (!blob
|| !hb_blob_get_length(blob
))
164 return hb_face_get_empty();
166 hb_face_for_data_closure_t
*closure
= hb_face_for_data_closure_create(
167 hb_blob_reference(blob
), index
);
170 return hb_face_get_empty();
172 face
= hb_face_create_for_tables(
173 hb_face_for_data_reference_table
,
175 (hb_destroy_func_t
)hb_face_for_data_closure_destroy
);
177 hb_face_set_index(face
, index
);
182 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
.graphite2
);
200 if (face
->shaper_data
.ot
201 && face
->shaper_data
.ot
!= HB_SHAPER_DATA_INVALID
202 && face
->shaper_data
.ot
!= HB_SHAPER_DATA_SUCCEEDED
)
203 hb_ot_shaper_face_data_destroy(face
->shaper_data
.ot
);
205 if (face
->shaper_data
.fallback
206 && face
->shaper_data
.fallback
!= HB_SHAPER_DATA_INVALID
207 && face
->shaper_data
.fallback
!= HB_SHAPER_DATA_SUCCEEDED
)
208 hb_fallback_shaper_face_data_destroy(face
->shaper_data
.fallback
);
211 face
->destroy(face
->user_data
);