b1897971f4dfeb3cafb0bdeb7aab2cf001f0f2bb
[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   return blob;
365 }
366
367 hb_face_t *
368 hb_face_create_for_data (hb_blob_t    *blob,
369                          unsigned int  index)
370 {
371   if (unlikely (!blob || !hb_blob_get_length (blob)))
372     return &_hb_face_nil;
373
374   hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (Sanitizer<OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
375
376   if (unlikely (!closure))
377     return &_hb_face_nil;
378
379   return hb_face_create_for_tables (_hb_face_for_data_get_table,
380                                     closure,
381                                     (hb_destroy_func_t) _hb_face_for_data_closure_destroy);
382 }
383
384
385 hb_face_t *
386 hb_face_reference (hb_face_t *face)
387 {
388   return hb_object_reference (face);
389 }
390
391 void
392 hb_face_destroy (hb_face_t *face)
393 {
394   if (!hb_object_destroy (face)) return;
395
396   _hb_ot_layout_destroy (face->ot_layout);
397
398   if (face->destroy)
399     face->destroy (face->user_data);
400
401   free (face);
402 }
403
404 hb_bool_t
405 hb_face_set_user_data (hb_face_t          *face,
406                        hb_user_data_key_t *key,
407                        void *              data,
408                        hb_destroy_func_t   destroy)
409 {
410   return hb_object_set_user_data (face, key, data, destroy);
411 }
412
413 void *
414 hb_face_get_user_data (hb_face_t          *face,
415                        hb_user_data_key_t *key)
416 {
417   return hb_object_get_user_data (face, key);
418 }
419
420
421 hb_blob_t *
422 hb_face_reference_table (hb_face_t *face,
423                          hb_tag_t   tag)
424 {
425   hb_blob_t *blob;
426
427   if (unlikely (!face || !face->get_table))
428     return hb_blob_get_empty ();
429
430   blob = face->get_table (tag, face->user_data);
431   if (unlikely (!blob))
432     return hb_blob_get_empty ();
433
434   return blob;
435 }
436
437 unsigned int
438 hb_face_get_upem (hb_face_t *face)
439 {
440   return _hb_ot_layout_get_upem (face);
441 }
442
443
444 /*
445  * hb_font_t
446  */
447
448 static hb_font_t _hb_font_nil = {
449   HB_OBJECT_HEADER_STATIC,
450
451   TRUE, /* immutable */
452
453   NULL, /* parent */
454   &_hb_face_nil,
455
456   0, /* x_scale */
457   0, /* y_scale */
458
459   0, /* x_ppem */
460   0, /* y_ppem */
461
462   &_hb_font_funcs_nil, /* klass */
463   NULL, /* user_data */
464   NULL  /* destroy */
465 };
466
467 hb_font_t *
468 hb_font_create (hb_face_t *face)
469 {
470   hb_font_t *font;
471
472   if (unlikely (!face))
473     face = &_hb_face_nil;
474   if (unlikely (hb_object_is_inert (face)))
475     return &_hb_font_nil;
476   if (!(font = hb_object_create<hb_font_t> ()))
477     return &_hb_font_nil;
478
479   font->face = hb_face_reference (face);
480   font->klass = &_hb_font_funcs_nil;
481
482   return font;
483 }
484
485 hb_font_t *
486 hb_font_create_sub_font (hb_font_t *parent)
487 {
488   if (unlikely (!parent))
489     return &_hb_font_nil;
490
491   hb_font_t *font = hb_font_create (parent->face);
492
493   if (unlikely (hb_object_is_inert (font)))
494     return font;
495
496   hb_font_make_immutable (parent);
497   font->parent = hb_font_reference (parent);
498
499   font->x_scale = parent->x_scale;
500   font->y_scale = parent->y_scale;
501   font->x_ppem = parent->x_ppem;
502   font->y_ppem = parent->y_ppem;
503
504   /* We can safely copy user_data from parent since we hold a reference
505    * onto it and it's immutable.  We should not copy the destroy notifiers
506    * though. */
507   font->klass = hb_font_funcs_reference (parent->klass);
508   font->user_data = parent->user_data;
509
510   return font;
511 }
512
513 hb_font_t *
514 hb_font_reference (hb_font_t *font)
515 {
516   return hb_object_reference (font);
517 }
518
519 void
520 hb_font_destroy (hb_font_t *font)
521 {
522   if (!hb_object_destroy (font)) return;
523
524   hb_font_destroy (font->parent);
525   hb_face_destroy (font->face);
526   hb_font_funcs_destroy (font->klass);
527   if (font->destroy)
528     font->destroy (font->user_data);
529
530   free (font);
531 }
532
533 hb_bool_t
534 hb_font_set_user_data (hb_font_t          *font,
535                        hb_user_data_key_t *key,
536                        void *              data,
537                        hb_destroy_func_t   destroy)
538 {
539   return hb_object_set_user_data (font, key, data, destroy);
540 }
541
542 void *
543 hb_font_get_user_data (hb_font_t          *font,
544                        hb_user_data_key_t *key)
545 {
546   return hb_object_get_user_data (font, key);
547 }
548
549 void
550 hb_font_make_immutable (hb_font_t *font)
551 {
552   if (hb_object_is_inert (font))
553     return;
554
555   font->immutable = true;
556 }
557
558 hb_bool_t
559 hb_font_is_immutable (hb_font_t *font)
560 {
561   return font->immutable;
562 }
563
564 hb_font_t *
565 hb_font_get_parent (hb_font_t *font)
566 {
567   return font->parent;
568 }
569
570 hb_face_t *
571 hb_font_get_face (hb_font_t *font)
572 {
573   return font->face;
574 }
575
576
577 void
578 hb_font_set_funcs (hb_font_t         *font,
579                    hb_font_funcs_t   *klass,
580                    void              *user_data,
581                    hb_destroy_func_t  destroy)
582 {
583   if (font->immutable)
584     return;
585
586   if (font->destroy)
587     font->destroy (font->user_data);
588
589   if (!klass)
590     klass = &_hb_font_funcs_nil;
591
592   hb_font_funcs_reference (klass);
593   hb_font_funcs_destroy (font->klass);
594   font->klass = klass;
595   font->user_data = user_data;
596   font->destroy = destroy;
597 }
598
599
600 void
601 hb_font_set_scale (hb_font_t *font,
602                    int x_scale,
603                    int y_scale)
604 {
605   if (font->immutable)
606     return;
607
608   font->x_scale = x_scale;
609   font->y_scale = y_scale;
610 }
611
612 void
613 hb_font_get_scale (hb_font_t *font,
614                    int *x_scale,
615                    int *y_scale)
616 {
617   if (x_scale) *x_scale = font->x_scale;
618   if (y_scale) *y_scale = font->y_scale;
619 }
620
621 void
622 hb_font_set_ppem (hb_font_t *font,
623                   unsigned int x_ppem,
624                   unsigned int y_ppem)
625 {
626   if (font->immutable)
627     return;
628
629   font->x_ppem = x_ppem;
630   font->y_ppem = y_ppem;
631 }
632
633 void
634 hb_font_get_ppem (hb_font_t *font,
635                   unsigned int *x_ppem,
636                   unsigned int *y_ppem)
637 {
638   if (x_ppem) *x_ppem = font->x_ppem;
639   if (y_ppem) *y_ppem = font->y_ppem;
640 }
641
642
643 HB_END_DECLS