hb-shape.cc 4.1 KB
Newer Older
B
Behdad Esfahbod 已提交
1
/*
B
Behdad Esfahbod 已提交
2
 * Copyright © 2009  Red Hat, Inc.
B
Behdad Esfahbod 已提交
3
 *
B
Behdad Esfahbod 已提交
4
 *  This is part of HarfBuzz, a text shaping library.
B
Behdad Esfahbod 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Red Hat Author(s): Behdad Esfahbod
 */

27
#include "hb-private.hh"
B
Behdad Esfahbod 已提交
28 29 30

#include "hb-shape.h"

31
#include "hb-buffer-private.hh"
B
Behdad Esfahbod 已提交
32

33 34
#ifdef HAVE_UNISCRIBE
# include "hb-uniscribe.h"
35
#endif
36 37 38 39 40 41 42 43 44 45 46 47
#ifdef HAVE_OT
# include "hb-ot-shape.h"
#endif
#include "hb-fallback-shape-private.hh"

typedef hb_bool_t (*hb_shape_func_t) (hb_font_t          *font,
				      hb_buffer_t        *buffer,
				      const hb_feature_t *features,
				      unsigned int        num_features,
				      const char         *shaper_options);

#define HB_SHAPER_IMPLEMENT(name) {#name, hb_##name##_shape}
B
Behdad Esfahbod 已提交
48 49
static struct hb_shaper_pair_t {
  char name[16];
50 51 52 53 54 55 56 57 58 59 60 61 62
  hb_shape_func_t func;
} shapers[] = {
  /* v--- Add new shapers in the right place here */
#ifdef HAVE_UNISCRIBE
  HB_SHAPER_IMPLEMENT (uniscribe),
#endif
#ifdef HAVE_OT
  HB_SHAPER_IMPLEMENT (ot),
#endif
  HB_SHAPER_IMPLEMENT (fallback) /* should be last */
};
#undef HB_SHAPER_IMPLEMENT

63 64
static struct static_shaper_list_t
{
B
Behdad Esfahbod 已提交
65 66
  static_shaper_list_t (void)
  {
67
    char *env = getenv ("HB_SHAPER_LIST");
B
Behdad Esfahbod 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
    if (env && *env)
    {
       /* Reorder shaper list to prefer requested shaper list. */
      unsigned int i = 0;
      char *end, *p = env;
      for (;;) {
        end = strchr (p, ',');
        if (!end)
          end = p + strlen (p);

	for (unsigned int j = i; j < ARRAY_LENGTH (shapers); j++)
	  if (end - p == strlen (shapers[j].name) &&
	      0 == strncmp (shapers[j].name, p, end - p))
	  {
	    /* Reorder this shaper to position i */
	   struct hb_shaper_pair_t t = shapers[j];
	   memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
	   shapers[i] = t;
	   i++;
	  }

        if (!*end)
          break;
        else
          p = end + 1;
      }
B
Behdad Esfahbod 已提交
94
    }
B
Behdad Esfahbod 已提交
95

B
Behdad Esfahbod 已提交
96 97 98 99 100
    ASSERT_STATIC ((ARRAY_LENGTH (shapers) + 1) * sizeof (*shaper_list) <= sizeof (shaper_list));
    unsigned int i;
    for (i = 0; i < ARRAY_LENGTH (shapers); i++)
      shaper_list[i] = shapers[i].name;
    shaper_list[i] = NULL;
B
Behdad Esfahbod 已提交
101 102
  }

B
Behdad Esfahbod 已提交
103
  const char *shaper_list[ARRAY_LENGTH (shapers) + 1];
B
Behdad Esfahbod 已提交
104 105 106 107 108 109 110
} static_shaper_list;

const char **
hb_shape_list_shapers (void)
{
  return static_shaper_list.shaper_list;
}
111 112

hb_bool_t
113 114 115 116 117 118
hb_shape_full (hb_font_t           *font,
	       hb_buffer_t         *buffer,
	       const hb_feature_t  *features,
	       unsigned int         num_features,
	       const char          *shaper_options,
	       const char         **shaper_list)
119
{
120 121 122 123 124 125 126 127 128
  if (likely (!shaper_list)) {
    for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
      if (likely (shapers[i].func (font, buffer,
				   features, num_features,
				   shaper_options)))
        return TRUE;
  } else {
    while (*shaper_list) {
      for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
129 130 131 132 133 134 135
	if (0 == strcmp (*shaper_list, shapers[i].name)) {
	  if (likely (shapers[i].func (font, buffer,
				       features, num_features,
				       shaper_options)))
	    return TRUE;
	  break;
	}
136
      shaper_list++;
137 138
    }
  }
139
  return FALSE;
140
}
141 142 143 144 145 146 147 148 149

void
hb_shape (hb_font_t           *font,
	  hb_buffer_t         *buffer,
	  const hb_feature_t  *features,
	  unsigned int         num_features)
{
  hb_shape_full (font, buffer, features, num_features, NULL, NULL);
}