Move code around
[profile/ivi/org.tizen.video-player.git] / src / hb-font.cc
1 /*
2  * Copyright © 2009  Red Hat, Inc.
3  *
4  *  This is part of HarfBuzz, a text shaping 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.hh"
28
29 #include "hb-ot-layout-private.hh"
30
31 #include "hb-font-private.hh"
32 #include "hb-blob.h"
33 #include "hb-open-file-private.hh"
34
35 #include <string.h>
36
37 HB_BEGIN_DECLS
38
39
40 /*
41  * hb_font_funcs_t
42  */
43
44 static hb_codepoint_t
45 hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
46                        const void *user_data HB_UNUSED,
47                        hb_codepoint_t unicode HB_UNUSED,
48                        hb_codepoint_t variation_selector HB_UNUSED)
49 { return 0; }
50
51 static void
52 hb_font_get_glyph_advance_nil (hb_font_t *font HB_UNUSED,
53                                const void *user_data HB_UNUSED,
54                                hb_codepoint_t glyph HB_UNUSED,
55                                hb_position_t *x_advance HB_UNUSED,
56                                hb_position_t *y_advance HB_UNUSED)
57 { }
58
59 static void
60 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
61                                const void *user_data HB_UNUSED,
62                                hb_codepoint_t glyph HB_UNUSED,
63                                hb_glyph_extents_t *extents HB_UNUSED)
64 { }
65
66 static hb_bool_t
67 hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED,
68                                const void *user_data HB_UNUSED,
69                                unsigned int point_index HB_UNUSED,
70                                hb_codepoint_t glyph HB_UNUSED,
71                                hb_position_t *x HB_UNUSED,
72                                hb_position_t *y HB_UNUSED)
73 { return false; }
74
75 static hb_position_t
76 hb_font_get_kerning_nil (hb_font_t *font HB_UNUSED,
77                          const void *user_data HB_UNUSED,
78                          hb_codepoint_t first_glyph HB_UNUSED,
79                          hb_codepoint_t second_glyph HB_UNUSED)
80 { return 0; }
81
82
83 static hb_font_funcs_t _hb_font_funcs_nil = {
84   HB_OBJECT_HEADER_STATIC,
85
86   TRUE,  /* immutable */
87   {
88     hb_font_get_glyph_nil,
89     hb_font_get_glyph_advance_nil,
90     hb_font_get_glyph_extents_nil,
91     hb_font_get_contour_point_nil,
92     hb_font_get_kerning_nil
93   }
94 };
95
96
97 hb_font_funcs_t *
98 hb_font_funcs_create (void)
99 {
100   hb_font_funcs_t *ffuncs;
101
102   if (!(ffuncs = hb_object_create<hb_font_funcs_t> ()))
103     return &_hb_font_funcs_nil;
104
105   ffuncs->v = _hb_font_funcs_nil.v;
106
107   return ffuncs;
108 }
109
110 hb_font_funcs_t *
111 hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
112 {
113   return hb_object_reference (ffuncs);
114 }
115
116 void
117 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
118 {
119   if (!hb_object_destroy (ffuncs)) return;
120
121   free (ffuncs);
122 }
123
124 hb_bool_t
125 hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
126                              hb_user_data_key_t *key,
127                              void *              data,
128                              hb_destroy_func_t   destroy)
129 {
130   return hb_object_set_user_data (ffuncs, key, data, destroy);
131 }
132
133 void *
134 hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
135                              hb_user_data_key_t *key)
136 {
137   return hb_object_get_user_data (ffuncs, key);
138 }
139
140
141 void
142 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
143 {
144   if (hb_object_is_inert (ffuncs))
145     return;
146
147   ffuncs->immutable = TRUE;
148 }
149
150 hb_bool_t
151 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
152 {
153   return ffuncs->immutable;
154 }
155
156
157 void
158 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
159                               hb_font_get_glyph_func_t glyph_func)
160 {
161   if (ffuncs->immutable)
162     return;
163
164   ffuncs->v.get_glyph = glyph_func ? glyph_func : hb_font_get_glyph_nil;
165 }
166
167 void
168 hb_font_funcs_set_glyph_advance_func (hb_font_funcs_t *ffuncs,
169                                       hb_font_get_glyph_advance_func_t glyph_advance_func)
170 {
171   if (ffuncs->immutable)
172     return;
173
174   ffuncs->v.get_glyph_advance = glyph_advance_func ? glyph_advance_func : hb_font_get_glyph_advance_nil;
175 }
176
177 void
178 hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
179                                       hb_font_get_glyph_extents_func_t glyph_extents_func)
180 {
181   if (ffuncs->immutable)
182     return;
183
184   ffuncs->v.get_glyph_extents = glyph_extents_func ? glyph_extents_func : hb_font_get_glyph_extents_nil;
185 }
186
187 void
188 hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs,
189                                       hb_font_get_contour_point_func_t contour_point_func)
190 {
191   if (ffuncs->immutable)
192     return;
193
194   ffuncs->v.get_contour_point = contour_point_func ? contour_point_func : hb_font_get_contour_point_nil;
195 }
196
197 void
198 hb_font_funcs_set_kerning_func (hb_font_funcs_t *ffuncs,
199                                 hb_font_get_kerning_func_t kerning_func)
200 {
201   if (ffuncs->immutable)
202     return;
203
204   ffuncs->v.get_kerning = kerning_func ? kerning_func : hb_font_get_kerning_nil;
205 }
206
207
208 hb_font_get_glyph_func_t
209 hb_font_funcs_get_glyph_func (hb_font_funcs_t *ffuncs)
210 {
211   return ffuncs->v.get_glyph;
212 }
213
214 hb_font_get_glyph_advance_func_t
215 hb_font_funcs_get_glyph_advance_func (hb_font_funcs_t *ffuncs)
216 {
217   return ffuncs->v.get_glyph_advance;
218 }
219
220 hb_font_get_glyph_extents_func_t
221 hb_font_funcs_get_glyph_extents_func (hb_font_funcs_t *ffuncs)
222 {
223   return ffuncs->v.get_glyph_extents;
224 }
225
226 hb_font_get_contour_point_func_t
227 hb_font_funcs_get_contour_point_func (hb_font_funcs_t *ffuncs)
228 {
229   return ffuncs->v.get_contour_point;
230 }
231
232 hb_font_get_kerning_func_t
233 hb_font_funcs_get_kerning_func (hb_font_funcs_t *ffuncs)
234 {
235   return ffuncs->v.get_kerning;
236 }
237
238
239
240 hb_codepoint_t
241 hb_font_get_glyph (hb_font_t *font,
242                    hb_codepoint_t unicode, hb_codepoint_t variation_selector)
243 {
244   return font->klass->v.get_glyph (font, font->user_data,
245                                    unicode, variation_selector);
246 }
247
248 void
249 hb_font_get_glyph_advance (hb_font_t *font,
250                            hb_codepoint_t glyph,
251                            hb_position_t *x_advance, hb_position_t *y_advance)
252 {
253   *x_advance = *y_advance = 0;
254   return font->klass->v.get_glyph_advance (font, font->user_data,
255                                            glyph, x_advance, y_advance);
256 }
257
258 void
259 hb_font_get_glyph_extents (hb_font_t *font,
260                            hb_codepoint_t glyph, hb_glyph_extents_t *extents)
261 {
262   memset (extents, 0, sizeof (*extents));
263   return font->klass->v.get_glyph_extents (font, font->user_data,
264                                            glyph, extents);
265 }
266
267 hb_bool_t
268 hb_font_get_contour_point (hb_font_t *font,
269                            unsigned int point_index,
270                            hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y)
271 {
272   *x = 0; *y = 0;
273   return font->klass->v.get_contour_point (font, font->user_data,
274                                            point_index,
275                                            glyph, x, y);
276 }
277
278 hb_position_t
279 hb_font_get_kerning (hb_font_t *font,
280                      hb_codepoint_t first_glyph, hb_codepoint_t second_glyph)
281 {
282   return font->klass->v.get_kerning (font, font->user_data,
283                                      first_glyph, second_glyph);
284 }
285
286
287 /*
288  * hb_face_t
289  */
290
291 static hb_face_t _hb_face_nil = {
292   HB_OBJECT_HEADER_STATIC,
293
294   NULL, /* get_table */
295   NULL, /* user_data */
296   NULL, /* destroy */
297
298   NULL  /* ot_layout */
299 };
300
301
302 hb_face_t *
303 hb_face_create_for_tables (hb_get_table_func_t  get_table,
304                            void                *user_data,
305                            hb_destroy_func_t    destroy)
306 {
307   hb_face_t *face;
308
309   if (!get_table || !(face = hb_object_create<hb_face_t> ())) {
310     if (destroy)
311       destroy (user_data);
312     return &_hb_face_nil;
313   }
314
315   face->get_table = get_table;
316   face->user_data = user_data;
317   face->destroy = destroy;
318
319   face->ot_layout = _hb_ot_layout_create (face);
320
321   return face;
322 }
323
324
325 typedef struct _hb_face_for_data_closure_t {
326   hb_blob_t *blob;
327   unsigned int  index;
328 } hb_face_for_data_closure_t;
329
330 static hb_face_for_data_closure_t *
331 _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
332 {
333   hb_face_for_data_closure_t *closure;
334
335   closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t));
336   if (unlikely (!closure))
337     return NULL;
338
339   closure->blob = blob;
340   closure->index = index;
341
342   return closure;
343 }
344
345 static void
346 _hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
347 {
348   hb_blob_destroy (closure->blob);
349   free (closure);
350 }
351
352 static hb_blob_t *
353 _hb_face_for_data_get_table (hb_tag_t tag, void *user_data)
354 {
355   hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
356
357   const OpenTypeFontFile &ot_file = *Sanitizer<OpenTypeFontFile>::lock_instance (data->blob);
358   const OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
359
360   const OpenTypeTable &table = ot_face.get_table_by_tag (tag);
361
362   hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
363
364   hb_blob_unlock (data->blob);
365
366   return blob;
367 }
368
369 hb_face_t *
370 hb_face_create_for_data (hb_blob_t    *blob,
371                          unsigned int  index)
372 {
373   if (unlikely (!blob || !hb_blob_get_length (blob)))
374     return &_hb_face_nil;
375
376   hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Sanitizer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
377
378   if (unlikely (!closure))
379     return &_hb_face_nil;
380
381   return hb_face_create_for_tables (_hb_face_for_data_get_table,
382                                     closure,
383                                     (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
384 }
385
386
387 hb_face_t *
388 hb_face_reference (hb_face_t *face)
389 {
390   return hb_object_reference (face);
391 }
392
393 void
394 hb_face_destroy (hb_face_t *face)
395 {
396   if (!hb_object_destroy (face)) return;
397
398   _hb_ot_layout_destroy (face->ot_layout);
399
400   if (face->destroy)
401     face->destroy (face->user_data);
402
403   free (face);
404 }
405
406 hb_bool_t
407 hb_face_set_user_data (hb_face_t          *face,
408                        hb_user_data_key_t *key,
409                        void *              data,
410                        hb_destroy_func_t   destroy)
411 {
412   return hb_object_set_user_data (face, key, data, destroy);
413 }
414
415 void *
416 hb_face_get_user_data (hb_face_t          *face,
417                        hb_user_data_key_t *key)
418 {
419   return hb_object_get_user_data (face, key);
420 }
421
422
423 hb_blob_t *
424 hb_face_reference_table (hb_face_t *face,
425                          hb_tag_t   tag)
426 {
427   hb_blob_t *blob;
428
429   if (unlikely (!face || !face->get_table))
430     return hb_blob_get_empty ();
431
432   blob = face->get_table (tag, face->user_data);
433   if (unlikely (!blob))
434     return hb_blob_get_empty ();
435
436   return blob;
437 }
438
439 unsigned int
440 hb_face_get_upem (hb_face_t *face)
441 {
442   return _hb_ot_layout_get_upem (face);
443 }
444
445
446 /*
447  * hb_font_t
448  */
449
450 static hb_font_t _hb_font_nil = {
451   HB_OBJECT_HEADER_STATIC,
452
453   &_hb_face_nil,
454
455   0, /* x_scale */
456   0, /* y_scale */
457
458   0, /* x_ppem */
459   0, /* y_ppem */
460
461   NULL, /* klass */
462   NULL, /* user_data */
463   NULL  /* destroy */
464 };
465
466 hb_font_t *
467 hb_font_create (hb_face_t *face)
468 {
469   hb_font_t *font;
470
471   if (unlikely (!face))
472     face = &_hb_face_nil;
473   if (unlikely (hb_object_is_inert (face)))
474     return &_hb_font_nil;
475   if (!(font = hb_object_create<hb_font_t> ()))
476     return &_hb_font_nil;
477
478   font->face = hb_face_reference (face);
479   font->klass = &_hb_font_funcs_nil;
480
481   return font;
482 }
483
484 hb_font_t *
485 hb_font_reference (hb_font_t *font)
486 {
487   return hb_object_reference (font);
488 }
489
490 void
491 hb_font_destroy (hb_font_t *font)
492 {
493   if (!hb_object_destroy (font)) return;
494
495   hb_face_destroy (font->face);
496   hb_font_funcs_destroy (font->klass);
497   if (font->destroy)
498     font->destroy (font->user_data);
499
500   free (font);
501 }
502
503 hb_bool_t
504 hb_font_set_user_data (hb_font_t          *font,
505                        hb_user_data_key_t *key,
506                        void *              data,
507                        hb_destroy_func_t   destroy)
508 {
509   return hb_object_set_user_data (font, key, data, destroy);
510 }
511
512 void *
513 hb_font_get_user_data (hb_font_t          *font,
514                        hb_user_data_key_t *key)
515 {
516   return hb_object_get_user_data (font, key);
517 }
518
519
520 hb_face_t *
521 hb_font_get_face (hb_font_t *font)
522 {
523   return font->face;
524 }
525
526
527 void
528 hb_font_set_funcs (hb_font_t         *font,
529                    hb_font_funcs_t   *klass,
530                    void              *user_data,
531                    hb_destroy_func_t  destroy)
532 {
533   if (hb_object_is_inert (font))
534     return;
535
536   if (font->destroy)
537     font->destroy (font->user_data);
538
539   if (!klass)
540     klass = &_hb_font_funcs_nil;
541
542   hb_font_funcs_reference (klass);
543   hb_font_funcs_destroy (font->klass);
544   font->klass = klass;
545   font->user_data = user_data;
546   font->destroy = destroy;
547 }
548
549 void
550 hb_font_unset_funcs (hb_font_t          *font,
551                      hb_font_funcs_t   **klass,
552                      void              **user_data,
553                      hb_destroy_func_t  *destroy)
554 {
555   /* None of the input arguments can be NULL. */
556
557   *klass = font->klass;
558   *user_data = font->user_data;
559   *destroy = font->destroy;
560
561   if (hb_object_is_inert (font))
562     return;
563
564   font->klass = NULL;
565   font->user_data = NULL;
566   font->destroy = NULL;
567 }
568
569 void
570 hb_font_set_scale (hb_font_t *font,
571                    int x_scale,
572                    int y_scale)
573 {
574   if (hb_object_is_inert (font))
575     return;
576
577   font->x_scale = x_scale;
578   font->y_scale = y_scale;
579 }
580
581 void
582 hb_font_get_scale (hb_font_t *font,
583                    int *x_scale,
584                    int *y_scale)
585 {
586   if (x_scale) *x_scale = font->x_scale;
587   if (y_scale) *y_scale = font->y_scale;
588 }
589
590 void
591 hb_font_set_ppem (hb_font_t *font,
592                   unsigned int x_ppem,
593                   unsigned int y_ppem)
594 {
595   if (hb_object_is_inert (font))
596     return;
597
598   font->x_ppem = x_ppem;
599   font->y_ppem = y_ppem;
600 }
601
602 void
603 hb_font_get_ppem (hb_font_t *font,
604                   unsigned int *x_ppem,
605                   unsigned int *y_ppem)
606 {
607   if (x_ppem) *x_ppem = font->x_ppem;
608   if (y_ppem) *y_ppem = font->y_ppem;
609 }
610
611
612 HB_END_DECLS