Add hb_font_get_*
[profile/ivi/org.tizen.video-player.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 #include <string.h>
36
37
38 /*
39  * hb_font_funcs_t
40  */
41
42 static hb_codepoint_t
43 hb_font_get_glyph_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
44                        hb_codepoint_t unicode, hb_codepoint_t variation_selector)
45 { return unicode; }
46
47 static hb_bool_t
48 hb_font_get_contour_point_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
49                                unsigned int point_index,
50                                hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y)
51 { return false; }
52
53 static void
54 hb_font_get_glyph_metrics_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
55                                hb_codepoint_t glyph, hb_glyph_metrics_t *metrics)
56 { memset (metrics, 0, sizeof (*metrics)); }
57
58 static hb_position_t
59 hb_font_get_kerning_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
60                          hb_codepoint_t first_glyph, hb_codepoint_t second_glyph)
61 { return 0; }
62
63 hb_font_funcs_t _hb_font_funcs_nil = {
64   HB_REFERENCE_COUNT_INVALID, /* ref_count */
65
66   TRUE,  /* immutable */
67
68   hb_font_get_glyph_nil,
69   hb_font_get_contour_point_nil,
70   hb_font_get_glyph_metrics_nil,
71   hb_font_get_kerning_nil
72 };
73
74 hb_font_funcs_t *
75 hb_font_funcs_create (void)
76 {
77   hb_font_funcs_t *ffuncs;
78
79   if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs))
80     return &_hb_font_funcs_nil;
81
82   return ffuncs;
83 }
84
85 hb_font_funcs_t *
86 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
87 {
88   HB_OBJECT_DO_REFERENCE (ffuncs);
89 }
90
91 unsigned int
92 hb_font_funcs_get_reference_count (hb_font_funcs_t *ffuncs)
93 {
94   HB_OBJECT_DO_GET_REFERENCE_COUNT (ffuncs);
95 }
96
97 void
98 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
99 {
100   HB_OBJECT_DO_DESTROY (ffuncs);
101
102   free (ffuncs);
103 }
104
105 hb_font_funcs_t *
106 hb_font_funcs_copy (hb_font_funcs_t *other_ffuncs)
107 {
108   hb_font_funcs_t *ffuncs;
109
110   if (!HB_OBJECT_DO_CREATE (hb_font_funcs_t, ffuncs))
111     return &_hb_font_funcs_nil;
112
113   *ffuncs = *other_ffuncs;
114
115   /* re-init refcount */
116   HB_OBJECT_DO_INIT (ffuncs);
117   ffuncs->immutable = FALSE;
118
119   return ffuncs;
120 }
121
122 void
123 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
124 {
125   if (HB_OBJECT_IS_INERT (ffuncs))
126     return;
127
128   ffuncs->immutable = TRUE;
129 }
130
131
132 void
133 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
134                               hb_font_get_glyph_func_t glyph_func)
135 {
136   if (ffuncs->immutable)
137     return;
138
139   ffuncs->get_glyph = glyph_func ? glyph_func : hb_font_get_glyph_nil;
140 }
141
142 void
143 hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs,
144                                       hb_font_get_contour_point_func_t contour_point_func)
145 {
146   if (ffuncs->immutable)
147     return;
148
149   ffuncs->get_contour_point = contour_point_func ? contour_point_func : hb_font_get_contour_point_nil;
150 }
151
152 void
153 hb_font_funcs_set_glyph_metrics_func (hb_font_funcs_t *ffuncs,
154                                       hb_font_get_glyph_metrics_func_t glyph_metrics_func)
155 {
156   if (ffuncs->immutable)
157     return;
158
159   ffuncs->get_glyph_metrics = glyph_metrics_func ? glyph_metrics_func : hb_font_get_glyph_metrics_nil;
160 }
161
162 void
163 hb_font_funcs_set_kerning_func (hb_font_funcs_t *ffuncs,
164                                 hb_font_get_kerning_func_t kerning_func)
165 {
166   if (ffuncs->immutable)
167     return;
168
169   ffuncs->get_kerning = kerning_func ? kerning_func : hb_font_get_kerning_nil;
170 }
171
172
173 hb_codepoint_t
174 hb_font_get_glyph (hb_font_t *font, hb_face_t *face,
175                    hb_codepoint_t unicode, hb_codepoint_t variation_selector)
176 {
177   return font->klass->get_glyph (font, face, font->user_data,
178                                  unicode, variation_selector);
179 }
180
181 hb_bool_t
182 hb_font_get_contour_point (hb_font_t *font, hb_face_t *face,
183                            unsigned int point_index,
184                            hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y)
185 {
186   return font->klass->get_contour_point (font, face, font->user_data,
187                                          point_index,
188                                          glyph, x, y);
189 }
190
191 void
192 hb_font_get_glyph_metrics (hb_font_t *font, hb_face_t *face,
193                            hb_codepoint_t glyph, hb_glyph_metrics_t *metrics)
194 {
195   /* TODO Zero metrics here? */
196   return font->klass->get_glyph_metrics (font, face, font->user_data,
197                                          glyph, metrics);
198 }
199
200 hb_position_t
201 hb_font_get_kerning (hb_font_t *font, hb_face_t *face,
202                      hb_codepoint_t first_glyph, hb_codepoint_t second_glyph)
203 {
204   return font->klass->get_kerning (font, face, font->user_data,
205                                    first_glyph, second_glyph);
206 }
207
208 /*
209  * hb_face_t
210  */
211
212 static hb_blob_t *
213 _hb_face_get_table_from_blob (hb_tag_t tag, void *user_data)
214 {
215   hb_face_t *face = (hb_face_t *) user_data;
216
217   const OpenTypeFontFile &ot_file = Sanitizer<OpenTypeFontFile>::lock_instance (face->blob);
218   const OpenTypeFontFace &ot_face = ot_file.get_face (face->index);
219
220   const OpenTypeTable &table = ot_face.get_table_by_tag (tag);
221
222   hb_blob_t *blob = hb_blob_create_sub_blob (face->blob, table.offset, table.length);
223
224   hb_blob_unlock (face->blob);
225
226   return blob;
227 }
228
229 static hb_face_t _hb_face_nil = {
230   HB_REFERENCE_COUNT_INVALID, /* ref_count */
231
232   NULL, /* blob */
233   0, /* index */
234
235   NULL, /* get_table */
236   NULL, /* destroy */
237   NULL, /* user_data */
238
239   {} /* ot_layout */
240 };
241
242 hb_face_t *
243 hb_face_create_for_tables (hb_get_table_func_t  get_table,
244                            hb_destroy_func_t    destroy,
245                            void                *user_data)
246 {
247   hb_face_t *face;
248
249   if (!HB_OBJECT_DO_CREATE (hb_face_t, face)) {
250     if (destroy)
251       destroy (user_data);
252     return &_hb_face_nil;
253   }
254
255   face->get_table = get_table;
256   face->destroy = destroy;
257   face->user_data = user_data;
258
259   _hb_ot_layout_init (face);
260
261   return face;
262 }
263
264 hb_face_t *
265 hb_face_create_for_data (hb_blob_t    *blob,
266                          unsigned int  index)
267 {
268   hb_face_t *face;
269
270   if (!HB_OBJECT_DO_CREATE (hb_face_t, face))
271     return &_hb_face_nil;
272
273   face->blob = Sanitizer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob));
274   face->index = index;
275   face->get_table = _hb_face_get_table_from_blob;
276   face->user_data = face;
277
278   _hb_ot_layout_init (face);
279
280   return face;
281 }
282
283 hb_face_t *
284 hb_face_reference (hb_face_t *face)
285 {
286   HB_OBJECT_DO_REFERENCE (face);
287 }
288
289 unsigned int
290 hb_face_get_reference_count (hb_face_t *face)
291 {
292   HB_OBJECT_DO_GET_REFERENCE_COUNT (face);
293 }
294
295 void
296 hb_face_destroy (hb_face_t *face)
297 {
298   HB_OBJECT_DO_DESTROY (face);
299
300   _hb_ot_layout_fini (face);
301
302   hb_blob_destroy (face->blob);
303
304   if (face->destroy)
305     face->destroy (face->user_data);
306
307   free (face);
308 }
309
310 hb_blob_t *
311 hb_face_get_table (hb_face_t *face,
312                    hb_tag_t   tag)
313 {
314   if (HB_UNLIKELY (!face || !face->get_table))
315     return hb_blob_create_empty ();
316
317   return face->get_table (tag, face->user_data);
318 }
319
320
321 /*
322  * hb_font_t
323  */
324
325 static hb_font_t _hb_font_nil = {
326   HB_REFERENCE_COUNT_INVALID, /* ref_count */
327
328   0, /* x_scale */
329   0, /* y_scale */
330
331   0, /* x_ppem */
332   0, /* y_ppem */
333
334   NULL, /* klass */
335   NULL, /* destroy */
336   NULL  /* user_data */
337 };
338
339 hb_font_t *
340 hb_font_create (void)
341 {
342   hb_font_t *font;
343
344   if (!HB_OBJECT_DO_CREATE (hb_font_t, font))
345     return &_hb_font_nil;
346
347   return font;
348 }
349
350 hb_font_t *
351 hb_font_reference (hb_font_t *font)
352 {
353   HB_OBJECT_DO_REFERENCE (font);
354 }
355
356 unsigned int
357 hb_font_get_reference_count (hb_font_t *font)
358 {
359   HB_OBJECT_DO_GET_REFERENCE_COUNT (font);
360 }
361
362 void
363 hb_font_destroy (hb_font_t *font)
364 {
365   HB_OBJECT_DO_DESTROY (font);
366
367   hb_font_funcs_destroy (font->klass);
368   if (font->destroy)
369     font->destroy (font->user_data);
370
371   free (font);
372 }
373
374 void
375 hb_font_set_funcs (hb_font_t         *font,
376                    hb_font_funcs_t   *klass,
377                    hb_destroy_func_t  destroy,
378                    void              *user_data)
379 {
380   if (HB_OBJECT_IS_INERT (font))
381     return;
382
383   if (font->destroy)
384     font->destroy (font->user_data);
385
386   hb_font_funcs_reference (klass);
387   hb_font_funcs_destroy (font->klass);
388   font->klass = klass;
389   font->destroy = destroy;
390   font->user_data = user_data;
391 }
392
393 void
394 hb_font_set_scale (hb_font_t *font,
395                    hb_16dot16_t x_scale,
396                    hb_16dot16_t y_scale)
397 {
398   if (HB_OBJECT_IS_INERT (font))
399     return;
400
401   font->x_scale = x_scale;
402   font->y_scale = y_scale;
403 }
404
405 void
406 hb_font_set_ppem (hb_font_t *font,
407                   unsigned int x_ppem,
408                   unsigned int y_ppem)
409 {
410   if (HB_OBJECT_IS_INERT (font))
411     return;
412
413   font->x_ppem = x_ppem;
414   font->y_ppem = y_ppem;
415 }
416