Imported Upstream version 0.9.3
[platform/upstream/harfbuzz.git] / src / hb-shape.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-shaper-private.hh"
30 #include "hb-shape-plan-private.hh"
31 #include "hb-buffer-private.hh"
32 #include "hb-font-private.hh"
33
34
35 static const char **static_shaper_list;
36
37 static
38 void free_static_shaper_list (void)
39 {
40   free (static_shaper_list);
41 }
42
43 const char **
44 hb_shape_list_shapers (void)
45 {
46 retry:
47   const char **shaper_list = (const char **) hb_atomic_ptr_get (&static_shaper_list);
48
49   if (unlikely (!shaper_list))
50   {
51     /* Not found; allocate one. */
52     shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
53     if (unlikely (!shaper_list)) {
54       static const char *nil_shaper_list[] = {NULL};
55       return nil_shaper_list;
56     }
57
58     const hb_shaper_pair_t *shapers = _hb_shapers_get ();
59     unsigned int i;
60     for (i = 0; i < HB_SHAPERS_COUNT; i++)
61       shaper_list[i] = shapers[i].name;
62     shaper_list[i] = NULL;
63
64     if (!hb_atomic_ptr_cmpexch (&static_shaper_list, NULL, shaper_list)) {
65       free (shaper_list);
66       goto retry;
67     }
68
69 #ifdef HAVE_ATEXIT
70     atexit (free_static_shaper_list); /* First person registers atexit() callback. */
71 #endif
72   }
73
74   return shaper_list;
75 }
76
77
78 hb_bool_t
79 hb_shape_full (hb_font_t          *font,
80                hb_buffer_t        *buffer,
81                const hb_feature_t *features,
82                unsigned int        num_features,
83                const char * const *shaper_list)
84 {
85   if (unlikely (!buffer->len))
86     return true;
87
88   buffer->guess_properties ();
89
90   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
91   hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
92   hb_shape_plan_destroy (shape_plan);
93   return res;
94 }
95
96 void
97 hb_shape (hb_font_t           *font,
98           hb_buffer_t         *buffer,
99           const hb_feature_t  *features,
100           unsigned int         num_features)
101 {
102   hb_shape_full (font, buffer, features, num_features, NULL);
103 }