Git init
[external/pango1.0.git] / pango / opentype / 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-unicode-private.h"
31 #include "hb-open-file-private.hh"
32 #include "hb-blob.h"
33
34 #include "hb-ot-layout-private.h"
35
36 /*
37  * hb_font_funcs_t
38  */
39
40 hb_font_funcs_t _hb_font_funcs_nil = {
41   HB_REFERENCE_COUNT_INVALID, /* ref_count */
42
43   TRUE,  /* immutable */
44
45   NULL, /* glyph_func */
46   NULL, /* contour_point_func */
47   NULL, /* glyph_metrics_func */
48   NULL  /* kerning_func */
49 };
50
51 hb_font_funcs_t *
52 hb_font_funcs_create (void)
53 {
54   hb_font_funcs_t *ffuncs;
55
56   if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs))
57     return &_hb_font_funcs_nil;
58
59   return ffuncs;
60 }
61
62 hb_font_funcs_t *
63 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
64 {
65   HB_OBJECT_DO_REFERENCE (ffuncs);
66 }
67
68 unsigned int
69 hb_font_funcs_get_reference_count (hb_font_funcs_t *ffuncs)
70 {
71   HB_OBJECT_DO_GET_REFERENCE_COUNT (ffuncs);
72 }
73
74 void
75 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
76 {
77   HB_OBJECT_DO_DESTROY (ffuncs);
78
79   free (ffuncs);
80 }
81
82 hb_font_funcs_t *
83 hb_font_funcs_copy (hb_font_funcs_t *other_ffuncs)
84 {
85   hb_font_funcs_t *ffuncs;
86
87   if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs))
88     return &_hb_font_funcs_nil;
89
90   *ffuncs = *other_ffuncs;
91
92   /* re-init refcount */
93   HB_OBJECT_DO_INIT (ffuncs);
94   ffuncs->immutable = FALSE;
95
96   return ffuncs;
97 }
98
99 void
100 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
101 {
102   if (HB_OBJECT_IS_INERT (ffuncs))
103     return;
104
105   ffuncs->immutable = TRUE;
106 }
107
108
109
110 /*
111  * hb_face_t
112  */
113
114 static hb_blob_t *
115 _hb_face_get_table_from_blob (hb_tag_t tag, void *user_data)
116 {
117   hb_face_t *face = (hb_face_t *) user_data;
118
119   const OpenTypeFontFile &ot_file = Sanitizer<OpenTypeFontFile>::lock_instance (face->blob);
120   const OpenTypeFontFace &ot_face = ot_file.get_face (face->index);
121
122   const OpenTypeTable &table = ot_face.get_table_by_tag (tag);
123
124   hb_blob_t *blob = hb_blob_create_sub_blob (face->blob, table.offset, table.length);
125
126   hb_blob_unlock (face->blob);
127
128   return blob;
129 }
130
131 static hb_face_t _hb_face_nil = {
132   HB_REFERENCE_COUNT_INVALID, /* ref_count */
133
134   NULL, /* blob */
135   0, /* index */
136
137   NULL, /* get_table */
138   NULL, /* destroy */
139   NULL, /* user_data */
140
141   &_hb_unicode_funcs_nil,  /* unicode */
142
143   {} /* ot_layout */
144 };
145
146 hb_face_t *
147 hb_face_create_for_tables (hb_get_table_func_t  get_table,
148                            hb_destroy_func_t    destroy,
149                            void                *user_data)
150 {
151   hb_face_t *face;
152
153   if (!HB_OBJECT_DO_CREATE (hb_face_t, face)) {
154     if (destroy)
155       destroy (user_data);
156     return &_hb_face_nil;
157   }
158
159   face->get_table = get_table;
160   face->destroy = destroy;
161   face->user_data = user_data;
162
163   _hb_ot_layout_init (face);
164
165   return face;
166 }
167
168 hb_face_t *
169 hb_face_create_for_data (hb_blob_t    *blob,
170                          unsigned int  index)
171 {
172   hb_face_t *face;
173
174   if (!HB_OBJECT_DO_CREATE (hb_face_t, face))
175     return &_hb_face_nil;
176
177   face->blob = Sanitizer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob));
178   face->index = index;
179   face->get_table = _hb_face_get_table_from_blob;
180   face->user_data = face;
181
182   _hb_ot_layout_init (face);
183
184   return face;
185 }
186
187 hb_face_t *
188 hb_face_reference (hb_face_t *face)
189 {
190   HB_OBJECT_DO_REFERENCE (face);
191 }
192
193 unsigned int
194 hb_face_get_reference_count (hb_face_t *face)
195 {
196   HB_OBJECT_DO_GET_REFERENCE_COUNT (face);
197 }
198
199 void
200 hb_face_destroy (hb_face_t *face)
201 {
202   HB_OBJECT_DO_DESTROY (face);
203
204   _hb_ot_layout_fini (face);
205
206   hb_blob_destroy (face->blob);
207
208   if (face->destroy)
209     face->destroy (face->user_data);
210
211   hb_unicode_funcs_destroy (face->unicode);
212
213   free (face);
214 }
215
216 void
217 hb_face_set_unicode_funcs (hb_face_t *face,
218                                hb_unicode_funcs_t *unicode)
219 {
220   if (HB_OBJECT_IS_INERT (face))
221     return;
222
223   hb_unicode_funcs_reference (unicode);
224   hb_unicode_funcs_destroy (face->unicode);
225   face->unicode = unicode;
226 }
227
228 hb_blob_t *
229 hb_face_get_table (hb_face_t *face,
230                    hb_tag_t   tag)
231 {
232   if (HB_UNLIKELY (!face || !face->get_table))
233     return hb_blob_create_empty ();
234
235   return face->get_table (tag, face->user_data);
236 }
237
238
239 /*
240  * hb_font_t
241  */
242
243 static hb_font_t _hb_font_nil = {
244   HB_REFERENCE_COUNT_INVALID, /* ref_count */
245
246   0, /* x_scale */
247   0, /* y_scale */
248
249   0, /* x_ppem */
250   0, /* y_ppem */
251
252   NULL /* klass */
253 };
254
255 hb_font_t *
256 hb_font_create (void)
257 {
258   hb_font_t *font;
259
260   if (!HB_OBJECT_DO_CREATE (hb_font_t, font))
261     return &_hb_font_nil;
262
263   return font;
264 }
265
266 hb_font_t *
267 hb_font_reference (hb_font_t *font)
268 {
269   HB_OBJECT_DO_REFERENCE (font);
270 }
271
272 unsigned int
273 hb_font_get_reference_count (hb_font_t *font)
274 {
275   HB_OBJECT_DO_GET_REFERENCE_COUNT (font);
276 }
277
278 void
279 hb_font_destroy (hb_font_t *font)
280 {
281   HB_OBJECT_DO_DESTROY (font);
282
283   hb_font_funcs_destroy (font->klass);
284
285   free (font);
286 }
287
288 void
289 hb_font_set_funcs (hb_font_t       *font,
290                    hb_font_funcs_t *klass)
291 {
292   if (HB_OBJECT_IS_INERT (font))
293     return;
294
295   hb_font_funcs_reference (klass);
296   hb_font_funcs_destroy (font->klass);
297   font->klass = klass;
298 }
299
300 void
301 hb_font_set_scale (hb_font_t *font,
302                    hb_16dot16_t x_scale,
303                    hb_16dot16_t y_scale)
304 {
305   if (HB_OBJECT_IS_INERT (font))
306     return;
307
308   font->x_scale = x_scale;
309   font->y_scale = y_scale;
310 }
311
312 void
313 hb_font_set_ppem (hb_font_t *font,
314                   unsigned int x_ppem,
315                   unsigned int y_ppem)
316 {
317   if (HB_OBJECT_IS_INERT (font))
318     return;
319
320   font->x_ppem = x_ppem;
321   font->y_ppem = y_ppem;
322 }
323