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