blob: d42be6cbddbb7736b4c504ef3b8eaa9effd8db5b [file] [log] [blame]
Behdad Esfahbod15232e22009-08-13 17:13:25 -04001/*
Behdad Esfahbod2409d5f2011-04-21 17:14:28 -04002 * Copyright © 2009 Red Hat, Inc.
Behdad Esfahbod15232e22009-08-13 17:13:25 -04003 *
Behdad Esfahbodc755cb32010-04-22 00:11:43 -04004 * This is part of HarfBuzz, a text shaping library.
Behdad Esfahbod15232e22009-08-13 17:13:25 -04005 *
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
Behdad Esfahbodc57d4542011-04-20 18:50:27 -040027#include "hb-private.hh"
Behdad Esfahbod15232e22009-08-13 17:13:25 -040028
29#include "hb-shape.h"
30
Behdad Esfahbod22da7fd2010-05-12 18:23:21 -040031#include "hb-buffer-private.hh"
Behdad Esfahbod2f50d872009-11-04 21:07:03 -050032
Behdad Esfahbod02aeca92011-08-04 22:31:05 -040033#ifdef HAVE_UNISCRIBE
34# include "hb-uniscribe.h"
Behdad Esfahbod305ba862010-05-21 14:02:20 +010035#endif
Behdad Esfahbod02aeca92011-08-04 22:31:05 -040036#ifdef HAVE_OT
37# include "hb-ot-shape.h"
38#endif
39#include "hb-fallback-shape-private.hh"
Behdad Esfahbod26d7a752009-12-20 17:58:25 +010040
Behdad Esfahbod02aeca92011-08-04 22:31:05 -040041typedef hb_bool_t (*hb_shape_func_t) (hb_font_t *font,
42 hb_buffer_t *buffer,
43 const hb_feature_t *features,
44 unsigned int num_features,
Behdad Esfahbod05015732011-08-10 16:25:56 +020045 const char * const *shaper_options);
Behdad Esfahbodacdba3f2010-07-23 15:11:18 -040046
Behdad Esfahbod02aeca92011-08-04 22:31:05 -040047#define HB_SHAPER_IMPLEMENT(name) {#name, hb_##name##_shape}
Behdad Esfahbod670c8732011-08-08 21:36:24 +020048static struct hb_shaper_pair_t {
49 char name[16];
Behdad Esfahbod02aeca92011-08-04 22:31:05 -040050 hb_shape_func_t func;
51} shapers[] = {
52 /* v--- Add new shapers in the right place here */
53#ifdef HAVE_UNISCRIBE
54 HB_SHAPER_IMPLEMENT (uniscribe),
55#endif
56#ifdef HAVE_OT
57 HB_SHAPER_IMPLEMENT (ot),
58#endif
59 HB_SHAPER_IMPLEMENT (fallback) /* should be last */
60};
61#undef HB_SHAPER_IMPLEMENT
Behdad Esfahbod26d7a752009-12-20 17:58:25 +010062
Behdad Esfahbodc62a8f12011-08-05 18:02:30 -040063static struct static_shaper_list_t
64{
Behdad Esfahbodc4d63ef2011-08-05 17:54:25 -040065 static_shaper_list_t (void)
66 {
Behdad Esfahbod02aeca92011-08-04 22:31:05 -040067 char *env = getenv ("HB_SHAPER_LIST");
Behdad Esfahbod670c8732011-08-08 21:36:24 +020068 if (env && *env)
69 {
70 /* Reorder shaper list to prefer requested shaper list. */
71 unsigned int i = 0;
72 char *end, *p = env;
73 for (;;) {
74 end = strchr (p, ',');
75 if (!end)
76 end = p + strlen (p);
77
78 for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++)
Behdad Esfahbod33ccc772011-08-09 00:43:24 +020079 if (end - p == (int) strlen (shapers[j].name) &&
Behdad Esfahbod670c8732011-08-08 21:36:24 +020080 0 == strncmp (shapers[j].name, p, end - p))
81 {
82 /* Reorder this shaper to position i */
83 struct hb_shaper_pair_t t = shapers[j];
84 memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
85 shapers[i] = t;
86 i++;
87 }
88
89 if (!*end)
90 break;
91 else
92 p = end + 1;
93 }
Behdad Esfahbod9da55452011-08-05 19:48:49 -040094 }
Behdad Esfahbodc4d63ef2011-08-05 17:54:25 -040095
Behdad Esfahbod670c8732011-08-08 21:36:24 +020096 ASSERT_STATIC ((ARRAY_LENGTH (shapers) + 1) * sizeof (*shaper_list) <= sizeof (shaper_list));
97 unsigned int i;
98 for (i = 0; i < ARRAY_LENGTH (shapers); i++)
99 shaper_list[i] = shapers[i].name;
100 shaper_list[i] = NULL;
Behdad Esfahbodc4d63ef2011-08-05 17:54:25 -0400101 }
102
Behdad Esfahbod670c8732011-08-08 21:36:24 +0200103 const char *shaper_list[ARRAY_LENGTH (shapers) + 1];
Behdad Esfahbod9da55452011-08-05 19:48:49 -0400104} static_shaper_list;
105
106const char **
107hb_shape_list_shapers (void)
108{
109 return static_shaper_list.shaper_list;
110}
Behdad Esfahbod02aeca92011-08-04 22:31:05 -0400111
112hb_bool_t
Behdad Esfahbod05015732011-08-10 16:25:56 +0200113hb_shape_full (hb_font_t *font,
114 hb_buffer_t *buffer,
115 const hb_feature_t *features,
116 unsigned int num_features,
117 const char * const *shaper_options,
118 const char * const *shaper_list)
Behdad Esfahbod15232e22009-08-13 17:13:25 -0400119{
Behdad Esfahbod02aeca92011-08-04 22:31:05 -0400120 if (likely (!shaper_list)) {
121 for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
122 if (likely (shapers[i].func (font, buffer,
123 features, num_features,
124 shaper_options)))
125 return TRUE;
126 } else {
127 while (*shaper_list) {
128 for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
Behdad Esfahbodff199ba2011-08-07 03:43:46 -0400129 if (0 == strcmp (*shaper_list, shapers[i].name)) {
130 if (likely (shapers[i].func (font, buffer,
131 features, num_features,
132 shaper_options)))
133 return TRUE;
134 break;
135 }
Behdad Esfahbod02aeca92011-08-04 22:31:05 -0400136 shaper_list++;
Behdad Esfahbod3286fc02011-03-16 14:53:32 -0300137 }
138 }
Behdad Esfahbod02aeca92011-08-04 22:31:05 -0400139 return FALSE;
Behdad Esfahbod3286fc02011-03-16 14:53:32 -0300140}
Behdad Esfahbod3ca6c4e2011-08-05 17:22:19 -0400141
142void
143hb_shape (hb_font_t *font,
144 hb_buffer_t *buffer,
145 const hb_feature_t *features,
146 unsigned int num_features)
147{
148 hb_shape_full (font, buffer, features, num_features, NULL, NULL);
149}