Imported Upstream version 2.3.1
[platform/upstream/harfbuzz.git] / src / hb-shape.cc
1 /*
2  * Copyright © 2009  Red Hat, Inc.
3  * Copyright © 2012  Google, Inc.
4  *
5  *  This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Red Hat Author(s): Behdad Esfahbod
26  * Google Author(s): Behdad Esfahbod
27  */
28
29 #include "hb.hh"
30
31 #include "hb-shaper.hh"
32 #include "hb-shape-plan.hh"
33 #include "hb-buffer.hh"
34 #include "hb-font.hh"
35 #include "hb-machinery.hh"
36
37
38 /**
39  * SECTION:hb-shape
40  * @title: hb-shape
41  * @short_description: Conversion of text strings into positioned glyphs
42  * @include: hb.h
43  *
44  * Shaping is the central operation of HarfBuzz. Shaping operates on buffers,
45  * which are sequences of Unicode characters that use the same font and have
46  * the same text direction, script, and language. After shaping the buffer
47  * contains the output glyphs and their positions.
48  **/
49
50
51 #if HB_USE_ATEXIT
52 static void free_static_shaper_list ();
53 #endif
54
55 static const char *nil_shaper_list[] = {nullptr};
56
57 static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *,
58                                                               hb_shaper_list_lazy_loader_t>
59 {
60   static const char ** create ()
61   {
62     const char **shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
63     if (unlikely (!shaper_list))
64       return nullptr;
65
66     const hb_shaper_entry_t *shapers = _hb_shapers_get ();
67     unsigned int i;
68     for (i = 0; i < HB_SHAPERS_COUNT; i++)
69       shaper_list[i] = shapers[i].name;
70     shaper_list[i] = nullptr;
71
72 #if HB_USE_ATEXIT
73     atexit (free_static_shaper_list);
74 #endif
75
76     return shaper_list;
77   }
78   static void destroy (const char **l)
79   { free (l); }
80   static const char ** get_null ()
81   { return nil_shaper_list; }
82 } static_shaper_list;
83
84 #if HB_USE_ATEXIT
85 static
86 void free_static_shaper_list ()
87 {
88   static_shaper_list.free_instance ();
89 }
90 #endif
91
92
93 /**
94  * hb_shape_list_shapers:
95  *
96  * Retrieves the list of shapers supported by HarfBuzz.
97  *
98  * Return value: (transfer none) (array zero-terminated=1): an array of
99  *    constant strings
100  *
101  * Since: 0.9.2
102  **/
103 const char **
104 hb_shape_list_shapers ()
105 {
106   return static_shaper_list.get_unconst ();
107 }
108
109
110 /**
111  * hb_shape_full:
112  * @font: an #hb_font_t to use for shaping
113  * @buffer: an #hb_buffer_t to shape
114  * @features: (array length=num_features) (allow-none): an array of user
115  *    specified #hb_feature_t or %NULL
116  * @num_features: the length of @features array
117  * @shaper_list: (array zero-terminated=1) (allow-none): a %NULL-terminated
118  *    array of shapers to use or %NULL
119  *
120  * See hb_shape() for details. If @shaper_list is not %NULL, the specified
121  * shapers will be used in the given order, otherwise the default shapers list
122  * will be used.
123  *
124  * Return value: false if all shapers failed, true otherwise
125  *
126  * Since: 0.9.2
127  **/
128 hb_bool_t
129 hb_shape_full (hb_font_t          *font,
130                hb_buffer_t        *buffer,
131                const hb_feature_t *features,
132                unsigned int        num_features,
133                const char * const *shaper_list)
134 {
135   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached2 (font->face, &buffer->props,
136                                                               features, num_features,
137                                                               font->coords, font->num_coords,
138                                                               shaper_list);
139   hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
140   hb_shape_plan_destroy (shape_plan);
141
142   if (res)
143     buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
144   return res;
145 }
146
147 /**
148  * hb_shape:
149  * @font: an #hb_font_t to use for shaping
150  * @buffer: an #hb_buffer_t to shape
151  * @features: (array length=num_features) (allow-none): an array of user
152  *    specified #hb_feature_t or %NULL
153  * @num_features: the length of @features array
154  *
155  * Shapes @buffer using @font turning its Unicode characters content to
156  * positioned glyphs. If @features is not %NULL, it will be used to control the
157  * features applied during shaping.
158  *
159  * Since: 0.9.2
160  **/
161 void
162 hb_shape (hb_font_t           *font,
163           hb_buffer_t         *buffer,
164           const hb_feature_t  *features,
165           unsigned int         num_features)
166 {
167   hb_shape_full (font, buffer, features, num_features, nullptr);
168 }