hb-shape.cc revision 3ca6c4ecc299295b6682fa2b6b9f83b213223bad
115232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod/*
22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2009  Red Hat, Inc.
315232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod *
4c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
515232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod *
615232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * Permission is hereby granted, without written agreement and without
715232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
815232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * software and its documentation for any purpose, provided that the
915232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
1015232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * all copies of this software.
1115232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod *
1215232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
1315232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
1415232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
1515232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
1615232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * DAMAGE.
1715232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod *
1815232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
1915232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
2015232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
2115232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
2215232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
2315232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod *
2415232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
2515232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod */
2615232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod
27c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#include "hb-private.hh"
2815232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod
2915232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod#include "hb-shape.h"
3015232e26f4a89dab1b6de35ad9d3d16e75bf93d0Behdad Esfahbod
3122da7fd94d6318c52df69d70470a85464ffc533dBehdad Esfahbod#include "hb-buffer-private.hh"
322f50d873680ce0a43b6ec79df1ac946b91f31e63Behdad Esfahbod
3302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#ifdef HAVE_UNISCRIBE
3402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod# include "hb-uniscribe.h"
35305ba8671553cd955c20a54db622666c0bb02532Behdad Esfahbod#endif
3602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#ifdef HAVE_OT
3702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod# include "hb-ot-shape.h"
3802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#endif
3902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#include "hb-fallback-shape-private.hh"
4002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
4102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodtypedef hb_bool_t (*hb_shape_func_t) (hb_font_t          *font,
4202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod				      hb_buffer_t        *buffer,
4302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod				      const hb_feature_t *features,
4402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod				      unsigned int        num_features,
4502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod				      const char         *shaper_options);
4602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
4702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#define HB_SHAPER_IMPLEMENT(name) {#name, hb_##name##_shape}
4802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodstatic const struct hb_shaper_pair_t {
4902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  const char name[16];
5002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  hb_shape_func_t func;
5102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod} shapers[] = {
5202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  /* v--- Add new shapers in the right place here */
5302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#ifdef HAVE_UNISCRIBE
5402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  HB_SHAPER_IMPLEMENT (uniscribe),
5502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#endif
5602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#ifdef HAVE_OT
5702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  HB_SHAPER_IMPLEMENT (ot),
5802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#endif
5902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  HB_SHAPER_IMPLEMENT (fallback) /* should be last */
6002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod};
6102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod#undef HB_SHAPER_IMPLEMENT
6202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
6302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodstatic class static_shaper_list_t {
6402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  public:
6502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  static_shaper_list_t (void) {
6602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    char *env = getenv ("HB_SHAPER_LIST");
6702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    shaper_list = NULL;
6802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    if (!env || !*env)
6902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      return;
7002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    unsigned int count = 3; /* initial, fallback, null */
7102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    for (const char *p = env; (p == strchr (p, ':')) && p++; )
7202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      count++;
7302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    if (count <= ARRAY_LENGTH (static_shaper_list))
7402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      shaper_list = static_shaper_list;
7502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    else
7602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      shaper_list = (const char **) malloc (count * sizeof (shaper_list[0]));
7702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
7802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    count = 0;
7902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    shaper_list[count++] = env;
8002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    for (char *p = env; (p == strchr (p, ':')) && (*p = '\0', TRUE) && p++; )
8102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      shaper_list[count++] = p;
8202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    shaper_list[count++] = "fallback";
8302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    shaper_list[count] = NULL;
8402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  }
8502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  const char **shaper_list;
8602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  const char *static_shaper_list[10];
8702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod} env_shaper_list;
8802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
8902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbodhb_bool_t
903ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbodhb_shape_full (hb_font_t           *font,
913ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod	       hb_buffer_t         *buffer,
923ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod	       const hb_feature_t  *features,
933ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod	       unsigned int         num_features,
943ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod	       const char          *shaper_options,
953ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod	       const char         **shaper_list)
963286fc0e9adc3f2874c9409e7fdb09e4d2b7dda1Behdad Esfahbod{
9702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  if (likely (!shaper_list))
9802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    shaper_list = env_shaper_list.shaper_list;
9902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod
10002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  if (likely (!shaper_list)) {
10102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
10202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      if (likely (shapers[i].func (font, buffer,
10302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod				   features, num_features,
10402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod				   shaper_options)))
10502aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod        return TRUE;
10602aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  } else {
10702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod    while (*shaper_list) {
10802aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
10902aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod	if (0 == strcmp (*shaper_list, shapers[i].name) &&
11002aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod	    likely (shapers[i].func (font, buffer,
11102aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod				     features, num_features,
11202aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod				     shaper_options)))
11302aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod	  return TRUE;
11402aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod      shaper_list++;
1153286fc0e9adc3f2874c9409e7fdb09e4d2b7dda1Behdad Esfahbod    }
1163286fc0e9adc3f2874c9409e7fdb09e4d2b7dda1Behdad Esfahbod  }
11702aeca985b570763342c35e99af90025bfa088d5Behdad Esfahbod  return FALSE;
1183286fc0e9adc3f2874c9409e7fdb09e4d2b7dda1Behdad Esfahbod}
1193ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod
1203ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbodvoid
1213ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbodhb_shape (hb_font_t           *font,
1223ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod	  hb_buffer_t         *buffer,
1233ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod	  const hb_feature_t  *features,
1243ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod	  unsigned int         num_features)
1253ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod{
1263ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod  hb_shape_full (font, buffer, features, num_features, NULL, NULL);
1273ca6c4ecc299295b6682fa2b6b9f83b213223badBehdad Esfahbod}
128