Start ft glue
[framework/uifw/harfbuzz.git] / src / hb-font.cc
1 /*
2  * Copyright (C) 2009  Red Hat, Inc.
3  *
4  *  This is part of HarfBuzz, an OpenType Layout engine library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Red Hat Author(s): Behdad Esfahbod
25  */
26
27 #include "hb-private.h"
28
29 #include "hb-font-private.h"
30 #include "hb-open-file-private.hh"
31 #include "hb-blob.h"
32
33 #include "hb-ot-layout-private.h"
34
35 /*
36  * hb_font_funcs_t
37  */
38
39 hb_font_funcs_t _hb_font_funcs_nil = {
40   HB_REFERENCE_COUNT_INVALID, /* ref_count */
41
42   TRUE,  /* immutable */
43
44   NULL, /* glyph_func */
45   NULL, /* contour_point_func */
46   NULL, /* glyph_metrics_func */
47   NULL  /* kerning_func */
48 };
49
50 hb_font_funcs_t *
51 hb_font_funcs_create (void)
52 {
53   hb_font_funcs_t *ffuncs;
54
55   if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs))
56     return &_hb_font_funcs_nil;
57
58   return ffuncs;
59 }
60
61 hb_font_funcs_t *
62 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
63 {
64   HB_OBJECT_DO_REFERENCE (ffuncs);
65 }
66
67 unsigned int
68 hb_font_funcs_get_reference_count (hb_font_funcs_t *ffuncs)
69 {
70   HB_OBJECT_DO_GET_REFERENCE_COUNT (ffuncs);
71 }
72
73 void
74 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
75 {
76   HB_OBJECT_DO_DESTROY (ffuncs);
77
78   free (ffuncs);
79 }
80
81 hb_font_funcs_t *
82 hb_font_funcs_copy (hb_font_funcs_t *other_ffuncs)
83 {
84   hb_font_funcs_t *ffuncs;
85
86   if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs))
87     return &_hb_font_funcs_nil;
88
89   *ffuncs = *other_ffuncs;
90
91   /* re-init refcount */
92   HB_OBJECT_DO_INIT (ffuncs);
93   ffuncs->immutable = FALSE;
94
95   return ffuncs;
96 }
97
98 void
99 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
100 {
101   if (HB_OBJECT_IS_INERT (ffuncs))
102     return;
103
104   ffuncs->immutable = TRUE;
105 }
106
107
108
109 /*
110  * hb_face_t
111  */
112
113 static hb_blob_t *
114 _hb_face_get_table_from_blob (hb_tag_t tag, void *user_data)
115 {
116   hb_face_t *face = (hb_face_t *) user_data;
117
118   const OpenTypeFontFile &ot_file = Sanitizer<OpenTypeFontFile>::lock_instance (face->blob);
119   const OpenTypeFontFace &ot_face = ot_file.get_face (face->index);
120
121   const OpenTypeTable &table = ot_face.get_table_by_tag (tag);
122
123   hb_blob_t *blob = hb_blob_create_sub_blob (face->blob, table.offset, table.length);
124
125   hb_blob_unlock (face->blob);
126
127   return blob;
128 }
129
130 static hb_face_t _hb_face_nil = {
131   HB_REFERENCE_COUNT_INVALID, /* ref_count */
132
133   NULL, /* blob */
134   0, /* index */
135
136   NULL, /* get_table */
137   NULL, /* destroy */
138   NULL, /* user_data */
139
140   {} /* ot_layout */
141 };
142
143 hb_face_t *
144 hb_face_create_for_tables (hb_get_table_func_t  get_table,
145                            hb_destroy_func_t    destroy,
146                            void                *user_data)
147 {
148   hb_face_t *face;
149
150   if (!HB_OBJECT_DO_CREATE (hb_face_t, face)) {
151     if (destroy)
152       destroy (user_data);
153     return &_hb_face_nil;
154   }
155
156   face->get_table = get_table;
157   face->destroy = destroy;
158   face->user_data = user_data;
159
160   _hb_ot_layout_init (face);
161
162   return face;
163 }
164
165 hb_face_t *
166 hb_face_create_for_data (hb_blob_t    *blob,
167                          unsigned int  index)
168 {
169   hb_face_t *face;
170
171   if (!HB_OBJECT_DO_CREATE (hb_face_t, face))
172     return &_hb_face_nil;
173
174   face->blob = Sanitizer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob));
175   face->index = index;
176   face->get_table = _hb_face_get_table_from_blob;
177   face->user_data = face;
178
179   _hb_ot_layout_init (face);
180
181   return face;
182 }
183
184 hb_face_t *
185 hb_face_reference (hb_face_t *face)
186 {
187   HB_OBJECT_DO_REFERENCE (face);
188 }
189
190 unsigned int
191 hb_face_get_reference_count (hb_face_t *face)
192 {
193   HB_OBJECT_DO_GET_REFERENCE_COUNT (face);
194 }
195
196 void
197 hb_face_destroy (hb_face_t *face)
198 {
199   HB_OBJECT_DO_DESTROY (face);
200
201   _hb_ot_layout_fini (face);
202
203   hb_blob_destroy (face->blob);
204
205   if (face->destroy)
206     face->destroy (face->user_data);
207
208   free (face);
209 }
210
211 hb_blob_t *
212 hb_face_get_table (hb_face_t *face,
213                    hb_tag_t   tag)
214 {
215   if (HB_UNLIKELY (!face || !face->get_table))
216     return hb_blob_create_empty ();
217
218   return face->get_table (tag, face->user_data);
219 }
220
221
222 /*
223  * hb_font_t
224  */
225
226 static hb_font_t _hb_font_nil = {
227   HB_REFERENCE_COUNT_INVALID, /* ref_count */
228
229   0, /* x_scale */
230   0, /* y_scale */
231
232   0, /* x_ppem */
233   0, /* y_ppem */
234
235   NULL, /* klass */
236   NULL, /* destroy */
237   NULL  /* user_data */
238 };
239
240 hb_font_t *
241 hb_font_create (void)
242 {
243   hb_font_t *font;
244
245   if (!HB_OBJECT_DO_CREATE (hb_font_t, font))
246     return &_hb_font_nil;
247
248   return font;
249 }
250
251 hb_font_t *
252 hb_font_reference (hb_font_t *font)
253 {
254   HB_OBJECT_DO_REFERENCE (font);
255 }
256
257 unsigned int
258 hb_font_get_reference_count (hb_font_t *font)
259 {
260   HB_OBJECT_DO_GET_REFERENCE_COUNT (font);
261 }
262
263 void
264 hb_font_destroy (hb_font_t *font)
265 {
266   HB_OBJECT_DO_DESTROY (font);
267
268   hb_font_funcs_destroy (font->klass);
269   if (font->destroy)
270     font->destroy (font->user_data);
271
272   free (font);
273 }
274
275 void
276 hb_font_set_funcs (hb_font_t         *font,
277                    hb_font_funcs_t   *klass,
278                    hb_destroy_func_t  destroy,
279                    void              *user_data)
280 {
281   if (HB_OBJECT_IS_INERT (font))
282     return;
283
284   if (font->destroy)
285     font->destroy (font->user_data);
286
287   hb_font_funcs_reference (klass);
288   hb_font_funcs_destroy (font->klass);
289   font->klass = klass;
290   font->destroy = destroy;
291   font->user_data = user_data;
292 }
293
294 void
295 hb_font_set_scale (hb_font_t *font,
296                    hb_16dot16_t x_scale,
297                    hb_16dot16_t y_scale)
298 {
299   if (HB_OBJECT_IS_INERT (font))
300     return;
301
302   font->x_scale = x_scale;
303   font->y_scale = y_scale;
304 }
305
306 void
307 hb_font_set_ppem (hb_font_t *font,
308                   unsigned int x_ppem,
309                   unsigned int y_ppem)
310 {
311   if (HB_OBJECT_IS_INERT (font))
312     return;
313
314   font->x_ppem = x_ppem;
315   font->y_ppem = y_ppem;
316 }
317